![](/img/trans.png)
[英]C# generics and subclassing - why must I not give the type parameter on ctor? (simple)
[英]C# subclassing with generics: I need an extra generic parameter for ctor, but how?
我有一堂课
public class LDBList<T> : List<T> where T : LDBRootClass {
// typical constructor
public LDBList(LDBList<T> x) : base(x) { }
...
}
但我想要一个额外的构造函数,它接受一个不同泛型类型(比如 A)的列表,以及一个将 A 转换为 T 的函数,然后从中构建 T 列表,例如
public LDBList(
Func<A, T> converter,
IList<A> aList)
{
foreach (var x in aList) {
this.Append(converter(x));
}
}
所以converter
是A->T
类型,所以我取一个A
列表并从中制作一个T
列表。 我的班级由T
参数化,所以很好。
但它抱怨“找不到类型或命名空间名称'A'”。
好的,所以它需要在我想的类上有一个A
泛型参数(它在构造函数上真的不喜欢它)。 但我把它放在哪里,事实上这甚至可能吗?
理论上,您可以将额外类型添加到类本身的泛型类型中:
public class LDBList<A, T> : List<T> where T : LDBRootClass
{
// typical constructor
public LDBList(LDBList<A, T> x) : base(x) { }
public LDBList(
Func<A, T> converter,
IList<A> aList)
{
foreach (var x in aList)
{
this.Append(converter(x));
}
}
}
但这当然意味着您需要使用额外的类型参数声明该类型的实例,除非您使用该特定构造函数,否则您甚至不需要该类型参数。 所以这不好。
你可以像这样声明一个辅助类:
public static class LDBListCreator
{
public static LDBList<T> CreateFrom<T, A>(Func<A, T> converter, IList<A> aList) where T: LDBRootClass
{
var result = new LDBList<T>();
result.AddRange(aList.Select(converter));
return result;
}
}
这假设LDBList<T>
具有默认构造函数。
但是经过检查,您应该能够看到创建这样一个简单的帮助类是毫无意义的。 如果您向接受IEnumerable<T>
(如List<T>
类具有)的列表类添加构造函数,如下所示:
public LDBList(IEnumerable<T> items) : base(items)
{
}
然后,您可以仅使用IEnumerable.Select()
构造LDBList<T>
的实例。
例如,给定:
public class LDBRootClass
{
}
public class DerivedLDBRootClass : LDBRootClass
{
public DerivedLDBRootClass(string value)
{
// .. whatever
}
}
然后,您可以非常简单地从List<string>
转换为LDBList<DerivedLDBRootClass>
无需任何额外的脚手架,如下所示:
var strings = new List<string> { "One", "Two", "Three", "Four", "Five" };
var result = new LDBList<DerivedLDBRootClass>(strings.Select(item => new DerivedLDBRootClass(item)));
我不相信您可以向这样的构造函数添加其他泛型类型。
我会重构转换器以进行创建并返回 LDBList 的实例,这样转换器充当从 A 的实例创建 LDBLists 的工厂。
public class Converter<T,A>
{
public LDbList<T> CreateLdbList(IList<A>) {
var list = new LdbList<T>();
// do the conversion here
return list;
}
}
然后,将用法更改为
var Converter<X,Y> = new Converter();
var result = Converter.Convert(originalData);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.