C# の仕様を読んだ後では、実際には理にかなっていますが、混乱する可能性があります。
各クラスには関連付けられたインスタンス型があり、ジェネリック クラス宣言の場合、インスタンス型は、型宣言から構築された型を作成することによって形成されます。指定された各型引数は、対応する型パラメーターです。
class C<T>
{
}
C<T>
は構築された型であり、インスタンス型は、型パラメーターを使用して型を構築するプロセスによって作成されます。
C<String> c = new C<String>();
コンパイラは構築された type を取得C<T>
し、指定された型パラメーターを使用して のインスタンス型C<String>
が作成されました。Generics はコンパイル時の構成要素にすぎず、すべてが実行時に閉じた構成された型の観点から実行されます。
それでは、あなたの質問をここでテストしてみましょう。
class C
{
public C<T>()
{
}
}
存在しない型を構築しようとしているため、これは不可能です。
C c = new C<String>();
implicit
またはとのexplicit
間の変換は何ですか? なにもない。意味がありません。C
C<String>
C
この例では は非ジェネリック型であるため、インスタンス型はクラス宣言そのものです。では、どのようC<String>
に構築すると思いますC
か?
あなたがしたいことの適切な宣言はこれです。
internal class Class<T>
{
private readonly Delegate _delegate;
public Class(Func<T> function)
{
_delegate = function;
}
}
ここでは、構築Class<T>
された型があるため、コンパイラによって適切なインスタンス型を作成できます。
Func<String> function = new Func<String>(() => { return String.Empty; });
Class<String> c = new Class<String>(function);
質問で希望する方法でそれをやろうとした場合。
Func<String> function = new Func<String>(() => { return String.Empty; });
Class c = new Class<String>(function);
構築された型は になりますがClass<String>
、これは type と同じではなく、どちらからもまたは変換C
はありません。これがコンパイラによって許可されている場合、不明で使用できない状態になります。implicit
explicit
C
構築された型について知っておく必要があるのは、これです。
class C<T>
{
public C<T>()
{
}
}
ジェネリック コンストラクターを明示的に宣言することはできませんが、これは有効ですが、実行時に閉じた型コンストラクターとしてのみ有効です。
C<String> c = new C<String>();
コンパイル時に、次のコンストラクターが作成されます。
public C<String>()
{
}
これが有効な理由です:
C<String> c = new C<String>(); // We just used the closed type constructor
あなたが望んでいたことが許されれば、このようなことが起こる可能性があります.
class C<T>
{
public C<U>()
{
}
}
// ???
C<String> c = new C<Int32>();
コンストラクトが許可された場合に発生する問題を確認できます。仕様はかなり長く、ジェネリック、型パラメーター、構築された型、閉じた型と開いた型、バインドされた型とバインドされていない型をカバーする多くのセクションがあります。
非常に混乱する可能性がありますが、これがコンパイラの規則で許可されていないことは良いことです。