C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 149 を表示中)
■86962 / )  Re[2]: フラグを操作するジェネリックメソッドを作る方法
□投稿者/ 魔界の仮面弁士 (1603回)-(2018/04/05(Thu) 18:55:51)
No86942 (MTK さん) に返信
> 調べてみたところバージョンは C# 6.0 でした。
> 7.2以上になった時には使えるようになると覚えておこうと思います。

Visual Studio との対応表を載せておきます。

C# 2.0 … VS2005
C# 3.0 … VS2008
C# 4.0 … VS2010
C# 5.0 … VS2012
C# 6.0 … VS2015
C# 7.0 … VS2017
C# 7.1 … VS2017 15.3
C# 7.2 … VS2017 15.5
C# 7.3 … 将来のバージョン (VS2017 15.7 ?)
C# 8.0 … 将来のバージョン



■No86908 (Azulean さん) に返信
> ジェネリックではできないかもしれません。
>>// 指定されたフラグを加算するメソッド
>>public static void AddFlag(ref FlagEnumA flag, FlagEnumA state)
>>{
>>  flag = flag | state;
>>}


型制約 where で列挙型を指定することについて、
将来的に実装する方向で提案されているようです。
https://github.com/dotnet/csharplang/issues/104

実現すれば、先のコードを
  public static void SetFlag<TEnum>(ref TEnum self, TEnum flag) where TEnum : System.Enum { self |= flag; }
あるいは
  public static void SetFlag<TEnum>(ref TEnum self, TEnum flag) where TEnum : enum(int) { self |= flag; }
などと書けるようになるかも!?


ちなみに上記の C# コードは、現行バージョンのコンパイラではエラーになるのですが、
下記の IL から生成した DLL を参照設定して使う分には、VS2005 世代の C# 2.0 であっても、

    FlagEnumA bits = FlagEnumA.Enable;
    BitFlagHelper.SetFlag(ref bits, FlagEnumA.Visible);
    Console.WriteLine(bits);   //「Visible, Enable」と出力される
    int intValue = 0x2;
    // BitFlagHelper.SetFlag(ref intValue, 0x10);  // 列挙型以外はコンパイルエラー

という処理を実現することができます。


//
// 下記を「C:\TEMP\Example.IL」の名で保存して、コマンドラインから
// 「C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe /DLL /OUT=C:\TEMP\Example.dll C:\TEMP\Example.IL」
// を実行すると、「C:\TEMP\Example.dll」が生成されます。
//
.assembly Example {}
.assembly extern mscorlib { .ver 2:0:0:0 }
.class public auto ansi abstract sealed beforefieldinit BitFlagHelper extends [mscorlib]System.Object
{
  .method public hidebysig
     static void SetFlag< ([mscorlib]System.Enum) TEnum> (
       !!TEnum& self,
       !!TEnum flag
     ) cil managed 
  {
    .maxstack 8
    ldarg.0
    dup
    ldind.u4
    ldarg.1
    or
    stind.i4 
    ret
  }
}

解決済み
返信 編集キー/


管理者用

- Child Tree -