覆盖至少一种方法

时间:2018-01-22 10:36:16

标签: c# virtual abstract method-overriding overrides

我们假设有以下课程:

public class foo{
    internal virtual object M1(/*args*/){return null;}
    internal virtual object[] M2(/*args*/){return null;}

    public SomeStruct SomeMethod(){
        return new SomeStruct
        {
            Obj = M1();
            ObjArr = M2();
        }
    }
}

使用以下结构:

public class SomeStruct
{
    public object Obj;
    public object[] ObjArr;
}

有没有办法确保(最好是在编译时)强制至少一个方法或foo类的一个方法被覆盖?

在任何人说出之前 - 我知道可以使用一种方法并检查结果是否为数组(或IEnumerable),然后将其分配给正确的字段,但这需要更多时间,然后只运行空方法。我只是想知道是否有可能这样做。

3 个答案:

答案 0 :(得分:3)

您可以标记方法abstract,然后您将被迫实施这两种方法。这似乎是最直接的解决方案:

internal abstract object M1(/*args*/){return null;}
internal abstract object[] M2(/*args*/){return null;}

另一个实际上太复杂的选择是写一个Roslyn代码分析器,它将检查代码并确定它是否有效。

作为旁注:您的字段也应该驻留在基类中。如果你想使它们的类型通用,你可以使用泛型。

答案 1 :(得分:2)

" No",基本上。至少,不是没有编写自己的自定义代码分析器(可能通过Roslyn),考虑如果X : foo覆盖M1会发生什么,Y : X会覆盖{{} 1}}。

答案 2 :(得分:0)

您需要在子类中创建一个新方法,该方法使用新的返回类型隐藏基类的实现。您不能使用虚方法来重载像您一样的方法。通过更改参数而不是返回类型来完成方法的重载。

因此要么隐藏子类中的父方法,要么创建一个具有其他名称的方法。

这是我能想到的,只是一个例子。

在此处.Net Fiddle

运行
using System;

public class a
{
    public virtual object s(int a)
    {
        return a + 1;
    }
}

public class b : a
{
    public virtual object[] s(int a)
    {
        var arr = new object[]{a + 2};
        return arr;
    }
}

public class c : b
{
    private a A = new a();
    private b B = new b();
    public c()
    {
        print(2);
    }

    public void print(int a)
    {
        var result = A.s(1);
        Console.WriteLine("result : " + result);

        var resultB = B.s(1);
        //or resultB = base.s(1);

        foreach (var r in resultB)
        {
            Console.WriteLine("result B : " + r);
        }
    }
}

public class Program
{
    public static void Main()
    {
        c C = new c();
    }
}