![](/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.