[英]How to create an abstract method with a parameter of type of implementing class
I have got a abstract class with an abstract method taking a parameter of the type of the implementing class. 我有一个抽象类,抽象方法采用实现类的类型的参数。 I can achieve this by generics like this: 我可以通过这样的泛型实现这一点:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
}
class MyClass : Clazz<MyClass>
{
public override void CopyFrom(Clazz<MyClass>)
{
// implementation
}
}
Unfortunately I need in one of the implementing classes a list of Clazz<T>
elements. 不幸的是,我需要在其中一个实现类中包含一个Clazz<T>
元素列表。 So how can I achieve this? 那我该怎么做呢?
List<Clazz<T>>
does not work. 因为List<Clazz<T>>
不起作用。 List<Clazz<MyClass>>
is too restrictive. List<Clazz<MyClass>>
限制性太强。 CopyFrom()
method in one of the implementing classes. 删除泛型和抽象方法确实有效(我当前的解决方案),但这样我就忘记在其中一个实现类中实现CopyFrom()
方法。 Edit: Here comes a more detailed example: I've got an abstract class: 编辑:这里有一个更详细的例子:我有一个抽象类:
abstract class Clazz<T>
{
public abstract void CopyFrom(Clazz<T> source);
// ...
}
And a derived class: 派生类:
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;
}
}
}
There are several other deriving classes, the GetAllItems()
Method is only needed in MyDerivedClass
. 还有其他几个派生类, GetAllItems()
方法仅在MyDerivedClass
需要。
You can make the respective method generic, too, and introduce a constraint that takes T
into account. 您也可以使相应的方法通用,并引入一个将T
考虑在内的约束。 If I understand well what you want to achieve, you can do this: 如果我很清楚你想要实现的目标,你可以这样做:
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
}
}
You can also easily include list processing in a descendant, like this: 您还可以轻松地在后代中包含列表处理,如下所示:
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
}
}
Then use can declare a descendant of MyClass
, which in turn is a Clazz<T>
, T
being MyClass
: 然后使用可以声明MyClass
的后代,而后者又是一个Clazz<T>
, T
是MyClass
:
class MyDescendant : MyClass
{
}
The following works: 以下作品:
List<MyDescendant> list = new List<MyDescendant>();
new MyClass().ProcessList(list);
In case of MyOtherClass
, the situation is a little bit different. 在MyOtherClass
的情况下,情况有点不同。 ProcessMyClassList
accepts a list of Clazz<T>
or its descendants; ProcessMyClassList
接受Clazz<T>
或其后代的列表; however, not those related to MyOtherClass
but to the good-ol' MyClass
. 然而,不是那些与MyOtherClass
相关的,而是与好的' MyClass
相关的那些。 This code works: 此代码有效:
List<MyDescendant> list = new List<MyDescendant>();
new MyOtherClass().ProcessMyClassList(list); // this works
But the following won't compile: 但以下内容无法编译:
List<MyOtherClass> list = new List<MyOtherClass>();
new MyOtherClass().ProcessList(list); // this works
new MyOtherClass().ProcessMyClassList(list); // this doesn't
would this suffice? 这样就够了吗? without more details it is hard to tell. 没有更多细节,很难说清楚。
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
}
}
Thank's everyone for your answers, but I think I have figured out a solution I can live with: I will remove the generics and add a typecheck, like in the solution from anikiforov: 感谢大家的答案,但我想我已经找到了一个可以忍受的解决方案:我将删除泛型并添加一个类型检查,就像anikiforov的解决方案一样:
Abstract class: 抽象类:
abstract class Clazz
{
public abstract void CopyFrom(Clazz source);
}
And the derived class: 派生类:
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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.