C# 如何使用实现类类型的参数创建抽象方法
我得到了一个抽象类,其抽象方法采用了实现类类型的参数。我可以通过以下泛型实现这一点:C# 如何使用实现类类型的参数创建抽象方法,c#,generics,abstract,C#,Generics,Abstract,我得到了一个抽象类,其抽象方法采用了实现类类型的参数。我可以通过以下泛型实现这一点: class MyOtherClass : Clazz<MyOtherClass> { public override void CopyFrom(Clazz<MyOtherClass> source) { // implementation } // this list processing is inherited public
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
}
}
抽象类Clazz
{
公开摘要(Clazz来源);
}
类别MyClass:Clazz
{
公共覆盖无效复制源(Clazz)
{
//实施
}
}
不幸的是,我需要一个实现类中的Clazz
元素列表。
那么我如何才能做到这一点呢
- 当然
不起作用列表
限制太多列表
- 删除泛型和抽象方法确实有效(我当前的解决方案),但这样我可能会忘记在一个实现类中实现
方法CopyFrom()
抽象类Clazz
{
公开摘要(Clazz来源);
// ...
}
和派生类:
类MyDerivedClass:Clazz
{
公共字符串文本;
私有只读列表_List=new List();
公共覆盖无效CopyFrom(MyDerivedClass源)
{
Text=source.Text;
}
私有列表GetAllItems()
{
列表=新列表();
列表。添加(此);
list.AddRange(_list);
}
私有类MySubClass:Clazz
{
公共整数;
public override void CopyFrom(MySubClass源)
{
数字=来源。数字;
}
}
}
还有其他几个派生类,
GetAllItems()
方法仅在MyDerivedClass
中需要。您也可以将相应的方法设置为泛型,并引入一个考虑到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
}
}
以下工作:
List<MyDescendant> list = new List<MyDescendant>();
new MyClass().ProcessList(list);
但以下内容无法编译:
List<MyOtherClass> list = new List<MyOtherClass>();
new MyOtherClass().ProcessList(list); // this works
new MyOtherClass().ProcessMyClassList(list); // this doesn't
List List=新列表();
新建MyOtherClass().ProcessList(列表);//这很有效
新建MyOtherClass().ProcessMyClassList(列表);//这并不重要
这样就足够了吗?没有更多的细节就很难说
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
}
}
接口ICopyMaker
{
作废CopyFrom(ICopyMaker来源);
}
抽象类Clazz:ICopyMaker
{
公开摘要(Clazz来源);
void ICopyMaker.CopyFrom(ICopyMaker源)
{
var src=源为Clazz;
if(src==null)return;//知道如何仅从相同类型的实例复制
copyrom(src);
}
}
类别MyClass:Clazz
{
私有列表_List=新列表();
公共覆盖无效复制源(Clazz c)
{
//实施
}
}
谢谢大家的回答,但我想我已经找到了一个可以接受的解决方案:
我将删除泛型并添加一个类型检查,如anikiforov的解决方案:
抽象类:
以及派生类:
类MyDerivedClass:Clazz
{
公共字符串文本;
私人名单(private List);;
公共覆盖无效复制源(Clazz源)
{
var src=源作为MyDerivedClass;
if(src==null)返回;
Text=src.Text;
}
公共列表GetAllItems()
{
var list=新列表();
列表。添加(此);
list.AddRange(_list);
退货清单;
}
类MyNestedClass:Clazz
{
公共整数;
公共覆盖无效复制源(Clazz源)
{
var src=源作为MyNestedClass;
if(src==null)返回;
编号=src.编号;
}
}
}
您需要列表的位置?作为抽象方法的参数,或者只是派生类中的字段/属性?请解释一下为什么List
限制太多?List
限制太多,因为我需要用不同类型的元素填充它,所有派生自Clazz
。我只需要将列表作为派生类中的一个字段。我还没有对此进行测试,但这样我就必须在所有派生类中实现方法ProcessList
,不是吗?因为我已经回答了上面的一个问题,我只需要在一个派生类中使用这个列表。那么就在派生类中声明它:-)对不起,如果我的Witte有点慢,但是你能修改你的示例来告诉我你的意思吗?在其他派生类中保持该方法未实现,或者从Clazz中删除抽象定义?@Tarkil更新了我的答案。希望有帮助。不幸的是,CopyFrom(Clazz c)
无法访问MyClass:Clazz
的字段。(无法解析符号)。CopyFrom(Clazz c)是在MyClass中声明的方法。它始终可以访问MyClass的任何成员。你能提供更多关于你所犯错误的细节吗?
List<MyOtherClass> list = new List<MyOtherClass>();
new MyOtherClass().ProcessList(list); // this works
new MyOtherClass().ProcessMyClassList(list); // this doesn't
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
}
}
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;
}
}
}