29

ジェネリックメソッドを持つことができる方法で、非ジェネリッククラスでジェネリックプロパティを持つことができないのはなぜだろうと思っていました。すなわち:

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

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

@Jon Skeet's answerを読みましたが、それは単なるステートメントであり、おそらく仕様のどこかにあります。

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

4

5 に答える 5

16

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

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

于 2011-12-23T21:59:39.407 に答える
12

Julian Bucknall によるこのジェネリック プロパティのブログ投稿は、非常に適切な説明です。本質的には、ヒープ割り当ての問題です。

于 2011-12-23T22:10:27.260 に答える
3

私の推測では、文法があいまいになる厄介なコーナーケースがいくつかあると思います。オフハンド、これはトリッキーかもしれないようです:

foo.Bar<Baz>=3;

次のように解析する必要があります。

foo.Bar<Baz> = 3;

または:

foo.Bar < Baz >= 3;
于 2012-01-06T02:52:01.737 に答える
0

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

于 2011-12-23T22:13:44.123 に答える