C# 使用泛型类型强制转换
我很确定有一个简单的答案围绕协方差,但我很难看到它 我有一门课是这样的:C# 使用泛型类型强制转换,c#,generics,casting,C#,Generics,Casting,我很确定有一个简单的答案围绕协方差,但我很难看到它 我有一门课是这样的: internal sealed class GenericCallbackClass<T> : SomeBaseClass where T : ICallbackMessageBase { public GenericCallbackClass(string activeId, T message) : base(activeId) { Message =
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; }
}
内部密封类GenericCallbackClass:SomeBaseClass
其中T:ICallbackMessageBase
{
公共GenericCallbackClass(字符串activeId,T消息)
:base(activeId)
{
消息=消息;
}
公共T消息{get;private set;}
}
然后,我创建了一个类的实例,该类实现了名为Foo的ICallbackMessageBase,并实例化了一个新的GenericCallbackClass,将其作为T的参数传入
e、 g.var myCallback=new-genericallback(“SomeID”,new-Foo())
现在我想将其转换为GenericCallback类的一个更通用的实例,因为我将使用Foo、Bar等创建许多这样的实例,但所有实例都实现了ICallbackMessageBase
所以我想做一些类似于var callback=myCallback的事情,作为GenericCallbackClass
看来我不能做这个演员。。。你知道我应该如何解决这个问题吗?在这种情况下,你为什么需要通用的
。您的GenericCallback类中是否有其他代码利用了
。否则,您可以依赖于每个对象的接口实现,并确保接口定义回调类中可能需要的任何公共属性或操作
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());
}
您是否考虑过使用中间基类
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; }
}
}
内部密封类GenericCallbackClass:GenericCallbackClassBase
其中T:ICallbackMessageBase
{
公共GenericCallbackClass(T消息)
:base(message){}
公共新信息
{
获取{return(T)base.Message;}
}
}
它基本上只是一个为消息属性添加类型检查和自动转换的包装器。然后,您将能够执行以下操作:
var g = new GenericCallbackClass<A>(a);
var g2 = g as GenericCallbackClassBase;
var g=新的GenericCallbackClass(a);
var g2=g作为GenericCallbackClassBase;
g.Message
属性的类型为A
,而g2.Message
属性的类型为ICallbackMessageBase
搜索“co-和contra-variance”,这里有很多问题都很像你的问题。你为什么还要在这里使用泛型?为什么类不是非泛型的,带有ICallbackMessageBase Message
?@svick同上。。。我也在想同样的事情。我认为你的代码做的和你想象的不一样。类型参数通常命名为T
或类似的名称,但您有一个命名为ICallbackMessageBase
。这非常令人困惑,因为该类型参数与实际接口类型ICallbackMessageBase
没有关系。您应该完全删除该类型参数。完全没有注意到这一点。在LinqPad中将其拼凑在一起,没有语法突出显示,只是盲目地复制这些:\r…现在不好意思地想知道为什么我自己引入了泛型。我得把它放在那些日子里!谢谢你的帮助。