2016-05-24 6 views
1

私はインターフェイスとジェネリックで遊んできました。C#一般的な略語とアップキャスティング

私が欲しいのはFoo<T>を簡略化することですFoo<T, int>これは合理的ですか?次のことはそれを受け入れる方法ですか?私の実際の質問は...ある何

using System.Diagnostics; 

namespace MyNamespace 
{ 
    public class Foo<T> : Foo<T, int> where T : class 
    { 
    } 

    public class Foo<T, U> where T : class 
    { 
     public void Bar() 
     { 
      Debug.WriteLine("this: " + GetType().Name + ", T: " + typeof(T).Name + ", U: " + typeof(U).Name); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var fooT = new Foo<string>(); 
      var fooTU = new Foo<string, int>(); 

      fooT.Bar(); 
      fooTU.Bar(); 
     } 
    } 
} 

があることも可能Tは同じタイプですFoo<T>からFoo<T, int>からアップ(ダウン?)キャストへ。これを言うことは理にかなっているのでしょうか、それとも共変反(これはまだ私を逃しています)と関係していますか?

私には、幾分無知な人間、この例ではFoo<string>Foo<string, int>は同じタイプですが、もちろん((Foo<string>) fooTU).Bar();は機能しません!

+1

あなたの "実際の質問"が*クラス* 'Foo 'と 'Foo 'についてのみであれば、できるだけあなたのサンプルを減らすのに役立ちます。実際にインターフェイスに興味がある場合は、それらがあなたの質問にどのように関係しているかを明確にしてください。 –

答えて

3

実際の質問は... Foo<T, int>からFoo<T>へのキャストアップ(ダウン?)可能ですか?Tは同じタイプです。これを言うことは理にかなっているのでしょうか、それとも共変反(これはまだ私を逃しています)と関係していますか?

実際のオブジェクトは、タイプFoo<T>である場合はFoo<string>Foo<string, int>からキャストすることができます。彼らは同じ名前を持っているという事実は、ここで完全に無関係である、それでは、それを変更してみましょう:

class Foo<T, U> {} 
class Bar<T> : Foo<T, int> 

今:

Foo<string, int> foo = new Foo<string, int>(); 
Bar<string> bar = (Bar<string>) foo; // Bang, throws 

しかし:

Foo<string, int> foo = new Bar<string>(); 
Bar<string> bar = (Bar<string>) foo; // This is fine 

ジェネリック医薬品はここにかなり無関係です、本当に...それは鋳造の通常の規則です。

+0

ああ、もちろん。ありがとう – Mardoxx

1

Foo<T, int>からFoo<T>へのアップキャストが可能です。ここで、Tは同じタイプです。

ない安全に - それはdogかもしれませんが、そうでない場合は、実行時に例外を取得するつもりだ - それはDogAnimalからキャストするようなものです。

同じ理由で、Foo<string, int>を受け取り、Foo<string>のように扱うこともできません。この例では

1

fooとFooのはこれが間違ってい

同じタイプです。 Foo<T>Foo<T,int>ですが、 Foo<T,int>は必ずしも Foo<T>である必要はありません。このため、 Foo<T>から Foo<T,int>にキャストすることができます(その逆もありません)。