使用通用类型进行转换

时间:2012-09-12 10:42:24

标签: c# generics casting

我很确定有一个简单的答案,围绕共同变化,但我很难看到它!

我有一个类似的课程:

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>

之类的事情

看来我不能做这个演员......我有什么想法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:5)

在这种情况下,为什么你需要Generic <T>。您的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());
}

答案 1 :(得分: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; }
    }
}

它基本上只是一个为message属性添加类型检查和自动转换的包装器。然后,您就可以执行此操作:

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

g.Message属性的类型为A,而g2.Message属性的类型为ICallbackMessageBase