我有以下课程(非常简化的版本):
public interface A { }
public abstract class A<TType, TContentType> : A where TType: A
{
public abstract void Initialise();
public abstract TType DeepCopy();
public TContentType Value { get; private set; }
}
public class B : A<B, double>
{
public override void Initialise() { this.Value = 3.0; }
public override B DeepCopy() { return new B(); }
}
public class C : A<C, char>
{
public override void Initialise() { this.Value = 'v'; }
public override C DeepCopy() { return new C(); }
}
我可以创建一个A类型的列表,如下所示:
public static List<A> CreateList()
{
List<A> myList = new List<A>();
myList.Add(new B());
myList.Add(new C());
return myList;
}
我想创建一个方法,给定A类型的单个对象,将根据指定的长度创建这些对象的列表。
例如:
public static List<A> CreateList(A baseA, int length)
{
List<A> myList = new List<A>();
for (int i = 0; i < length; i++)
{
// create a deep copy of baseA
// call the Initialise method on the new object
// add to the list
}
return myList;
}
我不确定如何在不知道A类型的情况下创建深层副本,因为A不包含任何内容..我是否需要为此创建一个通用方法?
非常感谢任何指针
答案 0 :(得分:1)
你的事情很复杂,首先你不需要指定泛型参数所属的对象的类型作为通用参数(TType
),因为我们已经有了这些信息。 / p>
这是一个解决方案。它有interface
IA
,上面有IA Clone()
方法。然后我们可以调用该方法并将其安全地转换为T
中的CreateList()
。 CreateList
需要具有您想要的类型的通用参数,因为A
/ B
/ C
的通用参数可以是任何参数。
public static List<T> CreateList<T>(T baseA, int length) where T : IA
{
var myList = new List<T>();
for (int i = 0; i < length; i++)
{
myList.Add((T)baseA.Clone());
}
return myList;
}
public interface IA
{
public abstract IA Clone();
}
public abstract class A<TContentType> : IA
{
public abstract void Initialise();
public TContentType Value { get; private set; }
}
public class B : A<double>
{
public override IA Clone()
{
var b = new B();
// transfer properties
return b;
}
//public override void Initialise() { this.Value = 3.0; }
}
public class C : A<char>
{
public override IA Clone()
{
var c = new C();
// transfer properties
return c;
}
//public override void Initialise() { this.Value = 'v'; }
}
答案 1 :(得分:1)
只是建议如何让你的方法工作: 如果你的参数的类型是 A ,那么显然 A 接口必须有 DeepCopy()和 Initialise()方法。另外,为了让您拥有返回特定类型对象的 DeepCopy()方法,您可以使用显式接口实现
public interface A
{
void Initialise();
A DeepCopy();
}
public abstract class A<TType, TContentType> : A where TType : A
{
public abstract void Initialise();
public abstract TType DeepCopy();
A A.DeepCopy() { return this.DeepCopy(); }
public TContentType Value { get; protected set; }
}
public class B : A<B, double>
{
public override void Initialise() { this.Value = 3.0; }
public override B DeepCopy() { return new B(); }
}
public class C : A<C, char>
{
public override void Initialise() { this.Value = 'v'; }
public override C DeepCopy() { return new C(); }
}
class Program
{
static void Main(string[] args)
{
List<A> listBC = CreateList();
List<A> list = CreateList(new B(), 3);
}
public static List<A> CreateList()
{
List<A> myList = new List<A>();
myList.Add(new B());
myList.Add(new C());
return myList;
}
public static List<A> CreateList(A baseA, int length)
{
List<A> myList = new List<A>(length);
for (int i = 0; i < length; i++)
{
A copy = baseA.DeepCopy();
copy.Initialise();
myList.Add(copy);
}
return myList;
}
}
我不知道您的真实代码,但DeepCopy() { return new B(); }
必须复制一些成员值吗?并且在填写带有副本的列表时 - 您是否真的需要将它们初始化或留下深层副本?
答案 2 :(得分:0)
没有内置方法可以创建正确的深层副本。需要深度复制的类型应该实现IClonable。
您可以从中继承A接口,然后在CreateList中调用Clone(),将其返回到所需类型。
public interface A: IClonable {
Initialize();
}
public static List<A> CreateList(A baseA, int length)
{
List<A> myList = new List<A>();
for (int i = 0; i < length; i++)
{
var copy = (A) baseA.Clone();
copy.initialize();
myList.Add(copy);
}
return myList;
}
缺点是Clone返回对象,而不是您继承的类型。但这是框架本身广泛使用的方法。