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);
}
我 运行 在最后一行遇到了麻烦,因为编译器无法识别 theVar
的 myValue
成员,因为它是 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 添加到此单一接口类型定义列表中。
我是 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);
}
我 运行 在最后一行遇到了麻烦,因为编译器无法识别 theVar
的 myValue
成员,因为它是 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 添加到此单一接口类型定义列表中。