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; }
}

然后,我创建了一个实现 ICallbackMessageBase 的类的实例,名为 Foo 并实例化一个新的 GenericCallbackClass,将其作为 T 的参数传入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>. 否则,您可以只依赖每个对象的接口实现,并确保接口定义了您可能需要在回调类中的任何公共属性或操作。

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是 type A,而g2.Message属性将是 type ICallbackMessageBase

于 2012-09-12T10:52:28.003 回答