Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用泛型类型强制转换_C#_Generics_Casting - Fatal编程技术网

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…现在不好意思地想知道为什么我自己引入了泛型。我得把它放在那些日子里!谢谢你的帮助。