如何使用实现类类型的参数创建抽象方法
本文关键字:参数 创建 抽象方法 类型 何使用 实现 | 更新日期: 2023-09-27 18:03:02
我有一个抽象类,它有一个抽象方法,采用实现类类型的参数。我可以通过这样的泛型来实现这一点:
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
中需要。
这就
足够了吗? 没有更多细节,很难说。
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
}
}
您也可以使相应的方法泛型,并引入考虑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
}
}
然后 use 可以声明 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
谢谢大家的回答,但我想我已经找到了我可以接受的解决方案:我将删除泛型并添加一个类型检查,就像在 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;
}
}
}