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我正在编辑与实体框架的关系,默认情况下,不会执行任何操作。否则,将有不必要的支票。这只是一个优化的东西,不是什么太重要的东西。把它抽象化,不要实现方法的主体?然后派生类必须实现它们