我有一个带抽象方法的抽象类,它接受实现类类型的参数。我可以通过这样的泛型实现这一点:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
}
class MyClass : Clazz<MyClass>
{
public override void CopyFrom(Clazz<MyClass>)
{
// implementation
}
}
不幸的是,我需要在其中一个实现类中列出Clazz<T>
个元素。
那我怎么能实现这个呢?
List<Clazz<T>>
不起作用。List<Clazz<MyClass>>
限制性太强。CopyFrom()
方法。编辑:这里有一个更详细的例子: 我有一个抽象的课程:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
// ...
}
派生类:
class MyDerivedClass : Clazz<MyDerivedClass >
{
public string Text;
private readonly List<MySubClass> _list = new List<MySubClass>();
public override void CopyFrom(MyDerivedClass source)
{
Text = source.Text;
}
private List<Clazz> GetAllItems()
{
List<Clazz> list = new List<Clazz>();
list.Add(this);
list.AddRange(_list);
}
private class MySubClass : Clazz<MySubClass>
{
public int Number;
public override void CopyFrom(MySubClass source)
{
Number = source.Number;
}
}
}
还有其他几个派生类,只有GetAllItems()
才需要MyDerivedClass
方法。
答案 0 :(得分:1)
您也可以使相应的方法通用,并引入一个考虑T
的约束。如果我很清楚你想要实现的目标,你可以这样做:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
public abstract void ProcessList<TDescendant>(List<TDescendant> list)
where TDescendant : Clazz<T>;
}
class MyClass : Clazz<MyClass>
{
public override void CopyFrom(Clazz<MyClass> source)
{
// implementation
}
public override void ProcessList<TDescendant>(List<TDescendant> list)
{
// implementation
}
}
您还可以轻松地在后代中包含列表处理,如下所示:
class MyOtherClass : Clazz<MyOtherClass>
{
public override void CopyFrom(Clazz<MyOtherClass> source)
{
// implementation
}
// this list processing is inherited
public override void ProcessList<TDescendant>(List<TDescendant> list)
{
// implementation
}
// this list processing is specific to this descendant only
public void ProcessMyClassList<TDescendant>(List<TDescendant> list)
where TDescendant : Clazz<TMyClass>
{
// implementation
}
}
然后使用可以声明MyClass
的后代,后者又是Clazz<T>
,T
是MyClass
:
class MyDescendant : MyClass
{
}
以下作品:
List<MyDescendant> list = new List<MyDescendant>();
new MyClass().ProcessList(list);
如果是MyOtherClass
,情况会有所不同。 ProcessMyClassList
接受Clazz<T>
或其后代的列表;然而,不是那些与MyOtherClass
相关的,而是与良好的'MyClass
相关的那些。此代码有效:
List<MyDescendant> list = new List<MyDescendant>();
new MyOtherClass().ProcessMyClassList(list); // this works
但以下内容无法编译:
List<MyOtherClass> list = new List<MyOtherClass>();
new MyOtherClass().ProcessList(list); // this works
new MyOtherClass().ProcessMyClassList(list); // this doesn't
答案 1 :(得分:1)
这样就够了吗?没有更多细节,很难说清楚。
interface ICopyMaker
{
void CopyFrom(ICopyMaker source);
}
abstract class Clazz<T> : ICopyMaker
{
public abstract void CopyFrom(Clazz<T> source);
void ICopyMaker.CopyFrom(ICopyMaker source)
{
var src = source as Clazz<T>;
if (src == null) return; // know how to copy only from the instances of the same type
CopyFrom(src);
}
}
class MyClass : Clazz<MyClass>
{
private List<ICopyMaker> _list = new List<ICopyMaker>();
public override void CopyFrom(Clazz<MyClass> c)
{
//implementation
}
}
答案 2 :(得分:0)
感谢大家的答案,但我想我已经找到了一个可以忍受的解决方案: 我将删除泛型并添加一个类型检查,就像anikiforov的解决方案一样:
抽象类:
abstract class Clazz
{
public abstract void CopyFrom(Clazz source);
}
派生类:
class MyDerivedClass : Clazz
{
public string Text;
private List<MyNestedClass> _list;
public override void CopyFrom(Clazz source)
{
var src = source as MyDerivedClass;
if (src == null) return;
Text = src.Text;
}
public List<Clazz> GetAllItems()
{
var list = new List<Clazz>();
list.Add(this);
list.AddRange(_list);
return list;
}
class MyNestedClass : Clazz
{
public int Number;
public override void CopyFrom(Clazz source)
{
var src = source as MyNestedClass;
if (src == null) return;
Number = src.Number;
}
}
}