2013-01-09 2 views
59

C#に関する同僚と話をしながら、彼は私にその出力を予測しなければならないC#コードを示しました。これは最初は単純に見えましたが、そうではありませんでした。私は本当になぜC#がこのように動作するのか理解できません。クイズ付きのC#でネストされたジェネリッククラスを理解する

コード:

public class A<T1> 
{ 
    public T1 a; 

    public class B<T2> : A<T2> 
    { 
     public T1 b; 

     public class C<T3> : B<T3> 
     { 
      public T1 c; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     A<int>.B<char>.C<bool> o = new A<int>.B<char>.C<bool>(); 

     Console.WriteLine(o.a.GetType()); 
     Console.WriteLine(o.b.GetType()); 
     Console.WriteLine(o.c.GetType()); 

     Console.ReadKey(); 
    } 
} 

出力は次のようになります。

System.Boolean 
System.Char 
System.Int32 

o.aがbool型であることを私が間違っているんだけど、私は理解している場合、私を修正しているためB<T3>B<T2>継承からC<T3>継承A<T2>から。また、のタイプがint型であることを少しでも理解できます。タイプがcの場合は、外部クラスから取得するT1です(私は思っています)。

o.bがchar型の理由を理解しようとすると、頭が爆発しています。これを私に説明できる人はいますか?

+38

私はあなたの会社でコードを維持していないとうれしいです。 – Default

+0

面白いですが、実用的な何かのためのトータルオーバーキル。私はこれが仕事のためではなくアカデミックであると仮定していますか? – JGilmartin

+4

@Defaultなぜですか?彼らは奇妙なC#コードでお互いをクイズしたいのですから? – Erix

答えて

40

これは古いパズルであり、非常に難しいです。私はアンデルス自身にそれを渡したとき、最初に答えを得られませんでした!

私はあなたの同僚はあなたを与えたバージョンは、サイラスさんのブログからだと思う:

http://blogs.msdn.com/b/cyrusn/archive/2005/08/01/446431.aspx

少し簡単なバージョンは、私のブログです。

http://blogs.msdn.com/b/ericlippert/archive/2007/07/27/an-inheritance-puzzle-part-one.aspx

私のバージョンへの解決策はここにある:

http://blogs.msdn.com/b/ericlippert/archive/2007/07/30/an-inheritance-puzzle-part-two.aspx

簡単に言うが、紛らわしい行動の理由は、あなたは外部クラスとの両方に存在する名前を持っている場合基本クラスは、 "基本クラス"になります。あなたが持っている場合には、次のとおりです。

public class B 
{ 
    public class X {} 
} 
public class P 
{ 
    public class X 
    { 
    public class D : B 
    { 
     public class N : X {} 
    } 
    } 
} 

その後P.X.D.NはないP.Xから、B.Xから継承します。このパズルでは、同じ宣言を "外側"と "ベース"の両方の検索パスで名前を付けることができるようにネストされたジェネリック型を作成しますが、異なるの意味があります。

とにかくブログ記事の説明を読んでください。それでも明確でない場合は、さらに具体的な質問をしてください。

8

私の最初の答えは間違っていました。

o.b.GetType()bはB<char>としてインスタンス化される周囲のクラスのメンバであり、A<char>から継承し、T1はcharと等しくなります。 何かなり明確ではありませんが、以下の(A_int.B_char.C_bool用マニュアルのインスタンス)である:ここでは

public class A_bool 
{ 
    public bool a; 

    public class B_bool : A_bool 
    { 
     public bool b; 
    } 
} 

public class A_char 
{ 
    public char a; 

    public class B_bool : A_bool 
    { 
     public char b; 
    } 
} 

public class A_int 
{ 
    public int a; 

    public class B_char : A_char 
    { 
     public int b; 

     public class C_bool : A_char.B_bool 
     { 
      public int c; 
     } 
    } 
} 

C_boolは右、同様A_bool.B_boolに由来しているだろうか?しかし、私たちはA_charに入れ子になっています。

+1

なぜo.cはboolではないのですか? C はB から継承し、次にA を継承します。 –

+1

はい継承型と囲み型の違いは混乱します。 'C 'は 'B 'で囲まれていますが、 'B ' – CubeSchrauber

+0

から継承しています。これは状況を説明する良い方法です! –

関連する問題