在派生自泛型的 class 集合中使用泛型基础 class
Use generic base class in a collection of classes derived from generic
我从 Java 转到 C#,但我无法找到解决以下问题的方法:
我有一个通用基础 class:
class MyBase<T> where T : SomeAncestorOfTs
{ ... }
然后是一些专门的 classes (A
,B
,C
...) 从它衍生出来,比如:
class A : MyBase<SomeSpecificT>
{ ... }
现在在我的代码中的某处,我想创建 MyBase
的各种后代的 Dictionary
:类似 Dictionary<string,MyBase<>>
的东西,但那是行不通的。
除了 Dictionary<String,Object>
之外,C# 中还有其他方法吗?
在 Java 中,这可以通过 HashMap<String,MyBase<? extends SomeAncestorOfTs>>
.
轻松实现
更新:T
应该有一个共同的基数 class (SomeAncestorOfT
).
这似乎工作正常,对你有帮助吗?
class Program
{
static void Main(string[] args)
{
Dictionary<string, MyBase> dic = new Dictionary<string, MyBase>();
A<int> test= new A<int>();
dic.Add("test", test);
}
}
class MyBase
{ }
class A<T> : MyBase
{}
class MyBase<T>
{ ... }
class A : MyBase<SomeSpecificT>
{ ... }
如果不想用Object,可以用dynamic。
var dict = new Dictionary<String, MyBase<dynamic>>();
不能直接那样做。我的建议是添加另一个非通用的基础 class:
class MyBase
{ ... }
class MyBase<T> : MyBase
{ ... }
然后制作该基数的字典:Dictionary<string,MyBase>
简短的回答是不您不能在 C# 中执行此操作。 MyBase<int>
和 MyBase<string>
除了 object
之外不共享碱基 class。就个人而言,即使它在语法上有效,我也不知道我会用它做什么。
如果所有这些实例共享一个行为,让它们都实现该接口并拥有这些接口的字典。
这样的事情怎么样:
public class SuperBase
{
}
internal class MyBase<T> : SuperBase
{
}
internal class A : MyBase<string>
{
public void DoStuff()
{
Dictionary<string, SuperBase> _dict = new Dictionary<string, SuperBase>();
_dict.Add("first", new MyBase<int>());
_dict.Add("second", new MyBase<object>());
_dict.Add("third", new MyBase<string>());
}
}
这至少不会产生编译错误(尽管我不能保证它不会在未来产生其他不可预见的麻烦)。
我从 Java 转到 C#,但我无法找到解决以下问题的方法:
我有一个通用基础 class:
class MyBase<T> where T : SomeAncestorOfTs
{ ... }
然后是一些专门的 classes (A
,B
,C
...) 从它衍生出来,比如:
class A : MyBase<SomeSpecificT>
{ ... }
现在在我的代码中的某处,我想创建 MyBase
的各种后代的 Dictionary
:类似 Dictionary<string,MyBase<>>
的东西,但那是行不通的。
除了 Dictionary<String,Object>
之外,C# 中还有其他方法吗?
在 Java 中,这可以通过 HashMap<String,MyBase<? extends SomeAncestorOfTs>>
.
更新:T
应该有一个共同的基数 class (SomeAncestorOfT
).
这似乎工作正常,对你有帮助吗?
class Program
{
static void Main(string[] args)
{
Dictionary<string, MyBase> dic = new Dictionary<string, MyBase>();
A<int> test= new A<int>();
dic.Add("test", test);
}
}
class MyBase
{ }
class A<T> : MyBase
{}
class MyBase<T>
{ ... }
class A : MyBase<SomeSpecificT>
{ ... }
如果不想用Object,可以用dynamic。
var dict = new Dictionary<String, MyBase<dynamic>>();
不能直接那样做。我的建议是添加另一个非通用的基础 class:
class MyBase
{ ... }
class MyBase<T> : MyBase
{ ... }
然后制作该基数的字典:Dictionary<string,MyBase>
简短的回答是不您不能在 C# 中执行此操作。 MyBase<int>
和 MyBase<string>
除了 object
之外不共享碱基 class。就个人而言,即使它在语法上有效,我也不知道我会用它做什么。
如果所有这些实例共享一个行为,让它们都实现该接口并拥有这些接口的字典。
这样的事情怎么样:
public class SuperBase
{
}
internal class MyBase<T> : SuperBase
{
}
internal class A : MyBase<string>
{
public void DoStuff()
{
Dictionary<string, SuperBase> _dict = new Dictionary<string, SuperBase>();
_dict.Add("first", new MyBase<int>());
_dict.Add("second", new MyBase<object>());
_dict.Add("third", new MyBase<string>());
}
}
这至少不会产生编译错误(尽管我不能保证它不会在未来产生其他不可预见的麻烦)。