无法将MyType <T>转换为MyType <object>

mpe*_*pen 2 c# syntax

我得到的具体例外是:

无法将类型的对象转换NbtByte为类型INbtTag<System.Object>

在这一行:

tag = (INbtTag<object>)new NbtByte(stream);
Run Code Online (Sandbox Code Playgroud)

在哪里tag声明:

INbtTag<object> tag;
Run Code Online (Sandbox Code Playgroud)

NbtByte定义为:

public class NbtByte : INbtTag<byte>
Run Code Online (Sandbox Code Playgroud)

在哪里IBtTag:

public interface INbtTag<out T>
Run Code Online (Sandbox Code Playgroud)

我想通过宣布它out T可以做到这样的事情.

基本上,我想要一本IbtTag<T>s 字典,

var dict = new Dictionary<string, INbtTag<object>>();
Run Code Online (Sandbox Code Playgroud)

但是T不同类型的地方(因此我宣布它object).这可能吗?

Ant*_*ram 7

接口差异仅适用于引用类型.排除值类型(例如整数,字节等,以及自定义结构).例如,IEnumerable<object>即使数组是,也不能使用整数数组IEnumerable<int>.

IEnumerable<object> objs = new int[] { 1, 2, 3 }; // illegal
IEnumerable<object> objs = new string[] { "a", "b", "c" }; // legal
Run Code Online (Sandbox Code Playgroud)

要解决字典问题,您可以选择定义非泛型接口.(如果您的通用接口可能将成员公开为类型T,那么非泛型接口只会公开object.)

说你有

interface INbtTag { } // non-generic interface 
interface INbtTag<out T> : INbtTag { } // covariant generic interface
Run Code Online (Sandbox Code Playgroud)

然后你可以用你的字典作为Dictionary<string, INbtTag>.

缺点是当您实现接口时,您必须实现这两者.这通常意味着隐式实现通用版本,而非显式实现非通用版本.例如:

interface INbtTag
{
    object GetValue(); 
}

interface INbtTag<out T> : INbtTag
{
    T GetValue();
}

class NbtByte : INbtTag<byte>
{
    byte value;

    public byte GetValue() // implicit implementation of generic interface
    {
        return value;
    }

    object INbtTag.GetValue() // explicit implementation of non-generic interface
    {
        return this.GetValue(); // delegates to method above
    }
}
Run Code Online (Sandbox Code Playgroud)