我们假设有以下课程:
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),然后将其分配给正确的字段,但这需要更多时间,然后只运行空方法。我只是想知道是否有可能这样做。
答案 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();
}
}