web-dev-qa-db-ja.com

C#がジェネリックプロパティを許可しないのはなぜですか?

非ジェネリッククラスでジェネリックプロパティを使用できないのに、ジェネリックメソッドを使用できないのはなぜですか。つまり:

public interface TestClass
{
   IEnumerable<T> GetAllBy<T>(); //this works

   IEnumerable<T> All<T> { get; } //this does not work
}

@Jon Skeetの answer を読みましたが、これは単なるステートメントであり、仕様のどこかにある可能性があります。

私の質問は、なぜ実際にそうなのかということです。この制限により、ある種の問題は回避されましたか?

28
Sunny Milenov

技術的には、CLRはプロパティではなくジェネリック型とメソッドのみをサポートしているため、問題はCLRに追加されなかった理由です。その答えは、おそらく「コストに見合うだけの十分な利益をもたらすとは考えられていなかった」ということでしょう。

しかし、より根本的には、型によってパラメータ化されたプロパティを持つことは意味的に意味がないため、メリットがないと見なされていました。 CarクラスにはWeightプロパティがあるかもしれませんが、Weight<Fruit>Weight<Giraffe>プロパティを持つことは意味がありません。

14
Timwi

この Generic Properties Julian Bucknallからのブログ投稿はかなり良い説明です。本質的には、ヒープ割り当ての問題です。

11
JamieSee

私の推測では、文法があいまいになるいくつかの厄介なコーナーケースがあります。手に負えない、これはトリッキーかもしれないようです:

foo.Bar<Baz>=3;

それを次のように解析する必要があります:

foo.Bar<Baz> = 3;

または:

foo.Bar < Baz >= 3;
2
munificent

自動ゲッター/セッターを使用しないことは、クラスレベルで「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」を定義するまで待つことができます。

0
viggity