C# 如果重写了另一个方法,则强制重写该方法
如果重写了另一个方法,是否有方法强制重写虚拟方法C# 如果重写了另一个方法,则强制重写该方法,c#,C#,如果重写了另一个方法,是否有方法强制重写虚拟方法 public class BaseClass { protected virtual void A() { // a default action called first } protected virtual void B() { // a default action called second that, // if A was override
public class BaseClass
{
protected virtual void A()
{
// a default action called first
}
protected virtual void B()
{
// a default action called second that,
// if A was overriden, makes no sense
}
}
编辑
谢谢你的回答。看到如何实现这一点非常令人费解,但对于我的明确案例来说,这并不至关重要
另外,我忘了提到这些方法将如何使用:(在基类中)
也许您不能通过编译器错误来强制它,但是您可以编写一个测试,通过某些属性来断言这些方法是同步的。还可以看到存在一些依赖性 一个粗略的例子如下:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class VersionAttribute : Attribute
{
public VersionAttribute(string version)
{
Version = version;
}
public string Version { get; set; }
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class DependentAttribute : Attribute
{
public string DependentOnMethod { get; set; }
public string DependentOnVersion { get; set; }
}
[Dependent(DependentOnMethod = "OtherMethod", DependentOnVersion = "1")]
public static void FirstMethod()
{
}
[Version("1")]
public static void OtherMethod()
{
}
以及确认版本号的测试:
[Test]
public void TestVersions()
{
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
foreach (var method in type.GetMethods())
{
foreach (var customAttribute in method.GetCustomAttributes())
{
var dependent = customAttribute as DependentAttribute;
if (dependent != null)
{
var methodInfo = type.GetMethod(dependent.DependentOnMethod);
Assert.That(methodInfo, Is.Not.Null, "Dependent method not found");
VersionAttribute version = methodInfo.GetCustomAttributes().OfType<VersionAttribute>().FirstOrDefault();
Assert.That(version, Is.Not.Null, "No version attribute on dependent method");
Assert.That(dependent.DependentOnVersion, Is.EqualTo(version.Version));
}
}
}
}
}
[测试]
公共void TestVersions()
{
foreach(Assembly.getExecutionGassembly().GetTypes()中的变量类型)
{
foreach(类型.GetMethods()中的var方法)
{
foreach(方法.GetCustomAttributes()中的var customAttribute)
{
var dependent=作为DependentAttribute的customAttribute;
if(依赖!=null)
{
var methodInfo=type.GetMethod(dependent.DependentOnMethod);
Assert.That(methodInfo,Is.Not.Null,“未找到依赖方法”);
VersionAttribute version=methodInfo.GetCustomAttributes().OfType().FirstOrDefault();
Assert.That(version,Is.Not.Null,“依赖方法上没有版本属性”);
Assert.That(dependent.DependentOnVersion,Is.EqualTo(version.version));
}
}
}
}
}
因此,如果更新某个方法,则需要更新
version
属性或Dependent
属性的版本号。希望总比没有好。不,你不能。但这让我想,你怎么能实现同样的理念
我想到的最好的主意是声明一个接口,其中包含要重写的方法包
public interface IMyOverridablePackage
{
void A_Override();
void B_Override();
}
然后为基类提供一个受保护的方法,其中子类可以显式重写方法集
protected void SetOverride(IMyOverridablePackage overridablePackage)
{
_overridablePackage = overridablePackage;
}
那么这里有两个类,一个覆盖方法集,一个不覆盖方法集:
public class NotOverriding : MyBaseClass
{
}
public sealed class Overriding : MyBaseClass, IMyOverridablePackage
{
public Overriding()
{
SetOverride(this);
}
void IMyOverridablePackage.A_Override()
{
Console.WriteLine("Overriding.A_Override");
}
void IMyOverridablePackage.B_Override()
{
Console.WriteLine("Overriding.B_Override");
}
}
以及基类的实现:
public abstract class MyBaseClass
{
private IMyOverridablePackage _overridablePackage;
public void A()
{
_overridablePackage.A_Override();
}
public void B()
{
_overridablePackage.B_Override();
}
private class MyDefaultPackage : IMyOverridablePackage
{
private readonly MyBaseClass _myBaseClass;
internal MyDefaultPackage(MyBaseClass myBaseClass)
{
_myBaseClass = myBaseClass;
}
void IMyOverridablePackage.A_Override()
{
_myBaseClass.A_Impl();
}
void IMyOverridablePackage.B_Override()
{
_myBaseClass.B_Impl();
}
}
protected MyBaseClass()
{
_overridablePackage = new MyDefaultPackage(this);
}
private void A_Impl()
{
Console.WriteLine("MyBaseClass.A_Impl");
}
private void B_Impl()
{
Console.WriteLine("MyBaseClass.B_Impl");
}
protected void SetOverride(IMyOverridablePackage overridablePackage)
{
_overridablePackage = overridablePackage;
}
}
public class Base
{
public Base()
{
var baseA = typeof (Base).GetRuntimeMethod("MethodA", new Type[0]);
var baseB = typeof (Base).GetRuntimeMethod("MethodB", new Type[0]);
var derivedA = GetType().GetRuntimeMethod("MethodA", new Type[0]);
var derivedB = GetType().GetRuntimeMethod("MethodB", new Type[0]);
if (baseA.DeclaringType == derivedA.DeclaringType ^
baseB.DeclaringType == derivedB.DeclaringType)
throw new InvalidOperationException("You must override MethodA and MethodB together.");
}
public virtual string MethodA() { return "Hello"; }
public virtual int MethodB() { return 123; }
}
这确实实现了目标,但您当然要问‘我想要多少?’是否值得额外的代码
这是一个有效的dotnetfiddle:您可以更改您的设计:
public abstract class BaseClass
{
protected abstract void A();
}
public class BaseClassEx
{
protected sealed override void A()
{
// action Calling B
}
protected virtual void B()
{
// a default action called second
}
}
在
Equals
(实际上都等于重载、具体类型和对象)和GetHashCode
的情况下,Resharper包含一条规则,每当您忘记实现其中一条规则时,它会以智能方式显示警告
您可以在基类的构造函数中通过运行时检查在代码中强制执行它:
public abstract class MyBaseClass
{
private IMyOverridablePackage _overridablePackage;
public void A()
{
_overridablePackage.A_Override();
}
public void B()
{
_overridablePackage.B_Override();
}
private class MyDefaultPackage : IMyOverridablePackage
{
private readonly MyBaseClass _myBaseClass;
internal MyDefaultPackage(MyBaseClass myBaseClass)
{
_myBaseClass = myBaseClass;
}
void IMyOverridablePackage.A_Override()
{
_myBaseClass.A_Impl();
}
void IMyOverridablePackage.B_Override()
{
_myBaseClass.B_Impl();
}
}
protected MyBaseClass()
{
_overridablePackage = new MyDefaultPackage(this);
}
private void A_Impl()
{
Console.WriteLine("MyBaseClass.A_Impl");
}
private void B_Impl()
{
Console.WriteLine("MyBaseClass.B_Impl");
}
protected void SetOverride(IMyOverridablePackage overridablePackage)
{
_overridablePackage = overridablePackage;
}
}
public class Base
{
public Base()
{
var baseA = typeof (Base).GetRuntimeMethod("MethodA", new Type[0]);
var baseB = typeof (Base).GetRuntimeMethod("MethodB", new Type[0]);
var derivedA = GetType().GetRuntimeMethod("MethodA", new Type[0]);
var derivedB = GetType().GetRuntimeMethod("MethodB", new Type[0]);
if (baseA.DeclaringType == derivedA.DeclaringType ^
baseB.DeclaringType == derivedB.DeclaringType)
throw new InvalidOperationException("You must override MethodA and MethodB together.");
}
public virtual string MethodA() { return "Hello"; }
public virtual int MethodB() { return 123; }
}
没有人强迫你重写
GetHashCode
如果Equals
被重写问题是如果A
被重写,为什么B
不再有意义。如果你重写其中一个,不重写另一个是一个糟糕的设计,它可能会生成警告(至少在某些静态分析工具中),但这不是法律禁止的language@TimSchmelter我正在编辑与实体框架的关系,默认情况下,不会执行任何操作。否则,将有不必要的支票。这只是一个优化的东西,不是什么太重要的东西。把它抽象化,不要实现方法的主体?然后派生类必须实现它们