非ジェネリッククラスでジェネリックプロパティを使用できないのに、ジェネリックメソッドを使用できないのはなぜですか。つまり:
public interface TestClass
{
IEnumerable<T> GetAllBy<T>(); //this works
IEnumerable<T> All<T> { get; } //this does not work
}
@Jon Skeetの answer を読みましたが、これは単なるステートメントであり、仕様のどこかにある可能性があります。
私の質問は、なぜ実際にそうなのかということです。この制限により、ある種の問題は回避されましたか?
技術的には、CLRはプロパティではなくジェネリック型とメソッドのみをサポートしているため、問題はCLRに追加されなかった理由です。その答えは、おそらく「コストに見合うだけの十分な利益をもたらすとは考えられていなかった」ということでしょう。
しかし、より根本的には、型によってパラメータ化されたプロパティを持つことは意味的に意味がないため、メリットがないと見なされていました。 Car
クラスにはWeight
プロパティがあるかもしれませんが、Weight<Fruit>
とWeight<Giraffe>
プロパティを持つことは意味がありません。
この Generic Properties Julian Bucknallからのブログ投稿はかなり良い説明です。本質的には、ヒープ割り当ての問題です。
私の推測では、文法があいまいになるいくつかの厄介なコーナーケースがあります。手に負えない、これはトリッキーかもしれないようです:
foo.Bar<Baz>=3;
それを次のように解析する必要があります:
foo.Bar<Baz> = 3;
または:
foo.Bar < Baz >= 3;
自動ゲッター/セッターを使用しないことは、クラスレベルで「T」が定義されていないとこれが不可能である理由を示しています。
それをコーディングしてみてください、自然なことはこれです:
IEnumerable<T> _all;
IEnumerable<T> All
{
get { return _all; }
}
フィールドは「T」を使用するため、「T」は、CLRが「T」が何であるかを知っているクラスにある必要があります。
メソッドを使用している場合、実際にメソッドを呼び出すまで「T」の定義を遅らせることができます。しかし、フィールド/プロパティでは、「T」はクラスレベルで1か所で宣言する必要があります。
クラスでTを宣言すると、プロパティの作成が非常に簡単になります。
public class TestClass<T>
{
IEnumerable<T> All { get; }
}
使用法:
var myTestClass = new TestClass<string>();
var stuff = myTestClass.All;
また、メソッドの「T」型パラメーターと同様に、実際にTestClassをインスタンス化して「T」を定義するまで待つことができます。