4

共分散を中心に展開するこれに対する簡単な答えがあると確信していますが、私はそれを見るのに苦労しています!

私は次のようなクラスを持っています:

internal sealed class GenericCallbackClass<T> : SomeBaseClass
    where T : ICallbackMessageBase
{
    public GenericCallbackClass(string activeId, T message)
        : base(activeId)
    {
        Message = message;
    }

    public T Message { get; private set; }
}

次に、Foo という名前の ICallbackMessageBase を実装するクラスのインスタンスを作成し、これを T の引数として渡す新しい GenericCallbackClass をインスタンス化します。var myCallback = new GenericCallback<Foo>("SomeID", new Foo())

これを GenericCallbackClass のより一般的なインスタンスにキャストしたいと考えています。これは、Foo、Bar などでこれの多くのインスタンスがあり、すべて ICallbackMessageBase を実装しているためです。

だから私は何かをしたいvar callback = myCallback as GenericCallbackClass<ICallbackMessageBase>

このキャストを実行できないようです...これを回避する方法はありますか?

4

2 に答える 2

5

<T>この状況でGeneric が必要なのはなぜですか。GenericCallback クラスに を活用する他のコードはありますか<T>。それ以外の場合は、各オブジェクトのインターフェイス実装に依存し、インターフェイスが Callback クラスで必要になる可能性のある共通のプロパティまたは操作を定義していることを確認できます。

public class SomeBaseClass 
{
   public SomeBaseClass (string activeId) 
   {
       //Persist activeId
   }
}

public interface ICallbackMessageBase { /* implementation */ } 
public class Foo : ICallbackMessageBase { /* implementation */ } 

internal sealed class GenericCallbackClass : SomeBaseClass
{
    public GenericCallbackClass(string activeId, ICallbackMessageBase message)
        : base(activeId)
    {
        Message = message;
    }

    public ICallbackMessageBase Message { get; private set; }
}

void Main()
{
    var specific = new GenericCallbackClass("foo", new Foo());
}
于 2012-09-12T10:49:54.680 に答える
1

中間基本クラスの使用を検討しましたか?

internal class GenericCallbackClassBase
{
    public GenericCallbackClassBase(ICallbackMessageBase message)
    {
        Message = message;
    }

    public ICallbackMessageBase Message { get; private set; }
}

次に、それからジェネリック バージョンを派生させることができます。

internal sealed class GenericCallbackClass<T> : GenericCallbackClassBase
where T : ICallbackMessageBase
{
    public GenericCallbackClass(T message)
        : base(message) { }

    public new T Message
    {
        get { return (T)base.Message; }
    }
}

これは基本的に、型チェックとメッセージ プロパティの自動キャストを追加する単なるラッパーです。その後、これを行うことができます:

var g = new GenericCallbackClass<A>(a);
var g2 = g as GenericCallbackClassBase;

g.Messageプロパティのタイプは になりますが、プロパティのタイプはAg2.MessageなりますICallbackMessageBase

于 2012-09-12T10:52:28.003 に答える