c#如何转换泛型类型

时间:2015-10-23 02:10:13

标签: c# generics casting

我想要转换字典,以便将值转换为由原始类型实现的接口;

首先:

public class DataRef<T> : IRef
{
      public int ID;
      public static Dictionary<int, T> LookUp = new Dictionary<int, T>();
}

public class Terrain : IThing
{
    ///IThing
    public ImageRef DefaultImageRef { get { return defaultImageRef; } }
    public string Name { get { return name; } }
    public string name = "unamed Terrain";

    //Other Stuff
    public TerrainType TerrainType = TerrainType.Floor;
    public ImageRef defaultImageRef = new ImageRef(typeof(Terrain));
    public ImageRef alternateImageRef = new ImageRef(typeof(Terrain));
    public int imageRef2;
}

public interface IThing
{
    ImageRef DefaultImageRef { get; }
    string Name { get; }
}

此表达式无法编译:

(Dictionary<int,IThing>)DataRef<Terrain>.LookUp

错误:

  

错误15无法转换类型   “System.Collections.Generic.Dictionary&LT; int,MO1.Definitions.Terrain&gt;'   至   “System.Collections.Generic.Dictionary&LT; int,MO1.Definitions.IThing&gt;' C:\ Projects \ MO1RPG \ VSsolution \ Editor \ Main.cs 28 72编辑

我想要转换字典,因为我想将它用作转换为“字典”的参数吗?有什么方法可以做到吗?

2 个答案:

答案 0 :(得分:4)

铸造无法做到这一点。您必须创建一个新字典。

起初它不直观,因为你可以这样做:

Terrain dataRef = new Terrain();
IThing thing = (IThing)dataRef;

但是你不允许这样做:

Dictionary<string, Terrain> dict = new Dictionary<string, Terrain>();
Dictionary<string, IThing> castDict = (Dictionary<string, IThing>)dict;

这里解释了不同之处:https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

简而言之,字典不是只读的,因此无法提供执行演员所需的某些保证。例如

Dictionary<string, Terrain> dict = new Dictionary<string, Terrain>();
Dictionary<string, IThing> castDict = (Dictionary<string, IThing>)dict;
castDict.Add("Rob", new DifferentThing()); // DifferentThing implements IThing

我们在此处所做的是将DifferentThing添加到字典中,该字典需要Terrain,这是一个很大的禁忌。为什么这是一个大禁忌?

因为如果有人这样做会怎么做:Terrain terr = dict["Rob"]; 现在,我们正在尝试将DifferentThing存储到Terrain

你需要记住的是,对象是而不是(当然有例外)创建一个新对象,而是改变我们在外部查看它的方式。

要从Dictionary<string, IThing>获得Dictionary<string, Terrain>,您需要创建一个定义为Dictionary<string, IThing> new 字典,并将其填入原始字典

见BrianMains&#39;回答这样做的方法

答案 1 :(得分:1)

您可以尝试使用Cast Linq方法,但您可能需要改为使用通用ToDictionary(k => k.Key, v => (IThing)v.Value);选项。