【问题标题】:How can I cast a subset of a dictionary to a type derived from Dictionary<>如何将字典的子集转换为从 Dictionary<> 派生的类型
【发布时间】:2013-06-01 09:16:10
【问题描述】:

为了简化使用特定类型的字典,我从通用 Dictionary 派生了一个类来处理从公共基类派生的各种元素:

//my base class holding a value
public abstract class A{ public int aValue; }

//derived classes that actually are stuffed into the dictionary
public class B : A {...}
public class C : A {...}

//wrapper class for dictionary
public class MyDict : Dictionary<string, A>;

//my class using the dictionary
public class MyClass {

  public MyDict dict = new MyDict();//use an instance of MyDict

  public MyClass() { ... //fill dict with instances of B and C }

  //function to return all elements of dict having a given value
  public MyDict GetSubSet(int testVal) {
    var ret = dict.Where(e => e.Value.aValue == testVal).
                       ToDictionary(k => k.Key, k => k.Value);
    return (MyDict) ret; // <- here I get a runtime InvalidCastException
  }
}

在将通用 Dictionary 包装到 MyDict 类中之前,转换成功(如果我将 MyDict 的所有实例替换为 Dictionary&lt;string,int&gt;,代码工作正常,即使没有在 return 语句中转换)。

我也尝试使用return ret as MyDict; 转换结果,但这将返回一个空值。像这样通过object 进行转换:return (MyDict) (object) ret; 也会失败并出现 InvalidCastException。

有人知道如何正确转换/转换返回值吗?

【问题讨论】:

    标签: c# generics casting derived


    【解决方案1】:

    由于ToDictionary 的结果不是MyDict,您会收到无效的强制转换异常。为了解决这个问题,向MyDict 添加一个构造函数,它接受一个IDictionary&lt;string,A&gt;,并从你的GetSubSet 方法返回调用该构造函数的结果:

    public class MyDict : Dictionary<string, A> {
        public MyDict() {
            // Perform the default initialization here
            ...
        }
        public MyDict(IDictionary<string,A> dict): base(dict) {
            // Initialize with data from the dict if necessary
            ...
        }
    }
    ...
    public MyDict GetSubSet(int testVal) {
        var ret = dict.Where(e => e.Value.aValue == testVal).
                       ToDictionary(k => k.Key, k => k.Value);
        return new MyDict(ret);
    }
    

    【讨论】:

    • 感谢您的提示,它有效。但是我试图找到一种方法来避免复制字典,因为它会影响性能。有没有办法直接使用ToDictionary(...)返回的Dictionary&lt;string,A&gt;作为返回值?
    • @AstaDev Making new MyDict 不会复制任何内容,因为字典是通过引用传递的。它直接使用 ToDictionary 的返回值,而不进行复制 - 它只是在其周围放置一个包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多