T
通常、型パラメーターをシール型 (型など) から派生するように制約することはできませんstruct
。適合できる型は 1 つしかないため、これは無意味であり、ジェネリックは必要ありません。したがって、次のような制約があります。
where T : string
また:
where T : DateTime
非常に正当な理由で違法です。
ただし、別の型パラメーターに制約する場合、その他の型パラメーターが実際の型に "置換" された (たまたまシールされた) 場合に、これが発生することがあります。クラスを考えてみましょう:
abstract class ExampleBase<TFromType>
{
internal abstract void M<TFromMethod>(TFromMethod value) where TFromMethod : TFromType;
}
これは非常に無実です。具体化では:
class ExampleOne : ExampleBase<string>
{
internal override void M<TFromMethod>(TFromMethod strangeString)
{
var a = string.IsNullOrEmpty(strangeString);
Console.WriteLine(a);
var b = strangeString.Substring(10, 2);
Console.WriteLine(b);
}
}
にTFromType
等しくしstring
ます。これは意味があるかもしれません。他のメンバー以外M<>
の ただし、M<>
それ自体は引き続き使用できます: コード:
var e1 = new ExampleOne();
e1.M("abcdefghijklmnopqrstuvwxyz");
実行して書き込みます:
間違い kl
コンソールに。したがって、制約は本質的に になりましwhere TFromMethod : string
たが、それでも問題ありませんでした。
この質問はTFromType
、 が値型の場合に何が起こるかについてです。そこで、今回は次のようにします。
class ExampleTwo : ExampleBase<DateTime>
{
internal override void M<TFromMethod>(TFromMethod strangeDate)
{
// var c = DateTime.SpecifyKind(strangeDate, DateTimeKind.Utc); // will not compile
// var d = strangeDate.AddDays(66.5); // will not compile
var e = string.Format(CultureInfo.InvariantCulture, "{0:D}", strangeDate); // OK, through boxing
Console.WriteLine(e);
var f = object.ReferenceEquals(strangeDate, strangeDate);
Console.WriteLine("Was 'strangeDate' a box? " + f);
}
}
では、なぜc
andd
宣言からの呼び出しが許可されていないのでしょうか? 結局、 .に制約されるstrangeDate
コンパイル時の型があります。だから確かに暗黙的に? 結局のところ、これは(上記)で機能しました。TFromMethod
DateTime
strangeDate
DateTime
string
class ExampleOne
公式のC#言語仕様の関連する場所を参照した回答を希望します。
を追加しようとするときに...d
と入力strangeDate.Ad
すると、IntelliSense (Visual Studio のオートコンプリート機能) が のすべてのアクセス可能なインスタンス メンバーのリストを表示するDateTime
ので、明らかに IntelliSense は呼び出しd
が正当であると判断することに注意してください!
もちろん、c
とd
をコメントアウトした後、 ExampleTwo
(withe
とf
) と次のコードを使用できます。
var e2 = new ExampleTwo();
e2.M(new DateTime(2015, 2, 13));
実行して書き出す:
2015 年 2 月 13 日金曜日 「strangeDate」はボックスでしたか? 間違い