2016-05-05 4 views
2

私はCで初めてですが、scalaで比較的経験があり、scalaのリストクラス(Consと静的クラスNilで拡張されています)を模倣しようとしています。私は.NETが4.0以降共分散/反分散をサポートしていたので、同様に型の振る舞いを得ることを望んでいました。共変(Covariant)とコントラバナント(contravariant)のモナド型ala Scala's List in C#

ScalaのREPL:C#ので

class A 
class B extends A 
class C extends A 

val x = new B() :: new B() 
//this is type List[B] 

val y = new C() :: new C() 
//this is type List[C] 

val z = new C() :: x 
//This uses contravariance to figure out and infer that this is type List[A]!!! 

をCとBがImmutableListと同じタイプではありませんので、これはコンパイラのエラーがスローされます私は、私が何を意味するかを示すために許可します。

オンラインでの例ではないようですが、私はまだC#の初心者ですので、C#が盲目的に試みる前にこれを行うことができるかどうか尋ねるのが賢明だと思いました(私はまだ試みていますが、私が行くにつれて、言語の残りの部分を最初に学んでいる)。

ありがとうございます!

+0

これは、リストの作成時に型推論をしたいように思える参照してください。これはコンパイルされません。 C#はそれを持っていません。 – juharr

+0

あなたは正しいと思っていましたが、C#には "var"キーワードが付いていますが、タイプ注釈を手動で解析する方法もあります(実行時に.NETに保持されています?)、型階層内で最も共通の祖先を見つけ出す(これはむしろ醜い)。 –

+0

私はこの型の推論を行うことができる前置き/追加操作をしたいだけです...方法はありますか? –

答えて

3

CおよびBは、ImmutableListを持つ同じタイプの ではないため、コンパイラエラーが発生します。 C#の

クラスは CO /反変はなく、これらはinoutキーワードを介して使用されるインタフェースと参加者の特性です。 C#では、List<T>という可変リストであり、Scalaの不変List[T]のようには動作しません。あなたは何ができるか

List<T>の基本型を宣言している:

void Main() 
{ 
    var list = new List<A>(); 
    list.Add(new B()); 
    list.Add(new C()); 
} 

class A { } 
class B : A { } 
class C : A { } 

同じTためのインタフェースを使用してのために行くが、あなたはそれよりもさらに行くことができません。 、そのの詳細について

void Main() 
{ 
    var bs = new List<B>(); 
    var cs = new List<C>(); 
    var result = bs.Concat(cs); 
} 

Why isn't there generic variance for classes in C# 4.0?

関連する問題