C# 泛型字典 类

C# Dictionary of generic classes

我是 C# 新手。我正在尝试在 C# 中实现一个字典,其 Java-等效项是:

HashMap<string, Variable<?>> dictionary

这是我正在尝试做的事情的详细 [​​=59=] 版本:

到目前为止,在 C# 中我有这样的东西:

interface IVariable { }

public class Variable<T> : IVariable
{
    public T myValue { get; set; }
}

Dictionary<string, IVariable> vars = new Dictionary<string, IVariable>();

然后我尝试这样做:

Variable<int> age = new Variable<int>();
age.myValue = 12;
vars.Add("age", age);
IVariable theVar;
if (vars.TryGetValue("age", out theVar) {
   Console.WriteLine("fetched age is " + theVar.myValue);
}

我 运行 在最后一行遇到了麻烦,因为编译器无法识别 theVarmyValue 成员,因为它是 IVariable.

在这个简单的例子中,也许我可以将 theVar 声明为 Variable<int> 而不是 IVariable 但我没有尝试过,因为它需要先验知识我从字典中获取的一种变量,我可能并不总是知道这些知识。

我不介意 myValue 是一个 inherited/abstract 属性(如果有的话),因为每个变量都有一个 属性 命名为 myValue(每个类型都不同,但名称不同)。在那种情况下,我想我可以使 IVariable 成为 abstract class 而不是 interface,但是我仍然 运行 陷入麻烦,因为 [= =14=].

我可以通过先用 is 检查其类型来将 theVar 转换为使用 as 的东西吗?我不确定这是否可行,甚至可能。

我查看了这些帖子以寻求指导(尤其是第二个):

Wildcard equivalent in C# generics

C# Generics: wildcards

但是,我的情况仍然与上面的第二个示例略有不同,因为该示例有一个抽象方法 returning a void 而我希望我的变量 return 非 void通用值。

感谢您的帮助。

C# 有 dynamic。您可以创建 Dictionary<string, dynamic>

或者您可以使用对象 (boxing/unboxing) Dictionary<string, object>

或者你可以获得generic type from class

class MyClass<TDicValue>
{
    Dictionary<strint, TDicValue> myDictionary;
}

我尝试使用 boxing/unboxing 并想出了这个解决方案。它似乎工作......到目前为止。但是好像不太安全。

public interface Variable
{
    object getValue();
    void setValue(object value);
    Type myType();
}

public class Variable<T>: Variable
{
    private T myValue;

    public object getValue() 
    {
        return myValue;
    }

    public void setValue(object value)
    {
        myValue = (T)value;
    }

    public Type myType() { return myValue.GetType(); }
}

    Dictionary<string, Variable> vars = new Dictionary<string, Variable>();

    Variable<int> age = new Variable<int>();
    age.setValue(21);
    vars.Add("age", age);
    Variable theAgeVar;
    vars.TryGetValue("age", out theAgeVar);
    Console.WriteLine("age = " + theAgeVar.getValue());

    Variable<double> height = new Variable<double>();
    height.setValue(5.9);
    Variable theHeightVar;
    vars.TryGetValue("age", out theHeightVar);
    Debug.Log("height = " + theHeightVar.getValue());

这会打印:

年龄 = 21

身高=5.9

我不喜欢的一件事是我必须将 getValue() 的 return 类型设为 object。例如,如果我希望 myValue(属于 T 类型)实现 IComparable,那么当装箱发生并且调用者收到 object 时,此信息将丢失。

我遇到了同样的问题,我有 20 种略有不同的类型,而且我不得不打开字典。我想将它们整理成一个列表。

问题是一样的,从带有反射或字符串的列表中选择正确的类型缺乏向 return 提供类型的能力。 @skrilmps 的回答是正确的,但是如果没有很多(公吨)丑陋的混乱代码,打包和解包充其量是不可靠的。

虽然 unity 在 2020 年确实支持动态,但这并不完全适用于我正在做的事情,除非我让所有动态都变得安全并且这是混乱的编码,不可扩展或不可维护,这听起来像是一场噩梦。

我个人觉得我是一个不合格的程序员,经过多年的努力学习,但我的努力仍然没有提供富有成效的 return 或值得注意的产品,所以我不能声称答案是我的,但在我对这个问题的正确解决方案的研究发现了这一点:https://www.youtube.com/watch?v=A7qwuFnyIpM

在这里,他基本上说,如果您将一个界面添加到类似的 class 中,这些界面旨在用于各种不同的列表,那么您可以改为制作该类型界面的列表。我也会假设字典,然后您可以将实现此接口的任何类型的 class 添加到此单一接口类型定义列表中。