Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用实现类类型的参数创建抽象方法_C#_Generics_Abstract - Fatal编程技术网

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;
        }
    }
}