C#泛型类字典

C# Dictionary of generic classes

我是C#的新手。我正在尝试使用Java等价的C#实现一个Dictionary:

1
HashMap<string, Variable< ? >> dictionary

这是我要执行的操作的详细Java版本:Java如何管理用户定义的变量

到目前为止,在C#中我有类似以下内容:

1
2
3
4
5
6
7
8
interface IVariable { }

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

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

然后我尝试执行此操作:

1
2
3
4
5
6
7
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是否是继承/抽象的属性(如果有这样的事情),因为每个变量都会有一个名为myValue的属性(每个变量的类型不同,但名称不同)。在那种情况下,我想我可以将IVariable设置为abstract class而不是interface,但随后我仍然遇到麻烦,要放入myValue类型的内容。

我可以先使用is检查is的类型,然后使用astheVar转换为某些内容吗?我不确定这是否可行或什至可行。

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

C#泛型中的通配符

C#泛型:通配符

但是,我的情况与上面的第二个示例仍然略有不同,因为该示例具有一个抽象方法,该方法返回一个void,而我希望我的变量返回非void泛型值。

感谢您的帮助。


C#具有动态功能。您可以创建Dictionary<string, dynamic>

或者您可以使用对象(装箱/拆箱)Dictionary<string, object>

或者您可以从类

中获取泛型类型

1
2
3
4
class MyClass<TDicValue>
{
    Dictionary<strint, TDicValue> myDictionary;
}


我遇到了同样的问题,我有20种略有不同的类型,并且我必须保留字典。我想将它们整理在一个列表中。

问题是相同的,从具有反射或字符串的列表中选择正确的类型缺乏提供返回类型的能力。 @skrilmps答案是正确的,但是如果没有大量(公吨)丑陋的凌乱代码,装箱和拆箱充其量是不可靠的。

虽然unity在2020年确实支持动态,但除非我使所有动态安全的东西都变得如此安全,混乱,无法扩展或可维护,听起来像是一场普遍的噩梦,否则这将无法与我的工作完全配合。

我个人认为,经过多年的尝试学习之后,我仍然是一个不足的程序员,但是仍然没有付出努力来提供丰硕的回报或成就,因此,我不能断定答案是我的,而是我在研究适当的解决方案时对于这个问题,我发现了这一点:https://www.youtube.com/watch?v=A7qwuFnyIpM

他在这里基本上说的是,如果将接口添加到打算用于各种不同列表的类似类中,则可以创建该类型接口的列表。我也会假设使用字典,然后您可以将实现此接口的任何类型的类添加到此单个接口类型定义的列表中。


我尝试使用装箱/拆箱,并提出了此解决方案。到目前为止,它似乎仍然有效。但这似乎不是很安全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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()的返回类型设置为object。例如,如果我希望myValue(类型为T)实现IComparable,则在装箱并且调用方收到object时,此信息会丢失。