如何根据类名的字符串检查类是否覆盖了特定的方法

本文关键字:覆盖 方法 是否 字符串 何根 检查 | 更新日期: 2023-09-27 18:01:42

我有一个基类叫做FormBA。有几个类根据Form_XXXX_BA的命名方案扩展了这个类(其中XXXX是表单的缩写名称)。给定表单的缩写名,我需要检查它是否覆盖了一个特定的方法(如果需要,我可以根据方法的输出来判断)

值得注意的事情:

  • 不是所有的形式都有一个Form_XXXX_BA,但我想要编辑我的代码,如果一个添加。
  • 我检查的方法是静态的,但是,它需要一个Form_XXXX_BA类作为参数。

我已经看过Activator.CreateInstanceSystem.Reflection,但是我还没有能够把我的头围绕它们如何帮助(尽管它们可能是解决方案,但我只是不理解它们)。

编辑:是的,通过扩展方法,我确实是指覆盖,我的错。固定的。

谢谢你的帮助到目前为止,抱歉我不清楚我的问题,虽然它看起来像六个字母变量可能在正确的轨道上。

我在系统上有一堆表格。对于某些表单,用户可以通过电子邮件将它们发送给另一个用户。目前,所有表单都有一个默认消息(FormsBA. getemailbody (FormsBA))。当前可发送的那些重写了此方法,因此根据表单本身设置body。(例如,对于表单ABC - Form_ABC_BA. getemailbody (Form_ABC_BA))

现在的问题是,现在有一个管理面板为每个单独的表单启用/禁用电子邮件。如果表单没有这个自定义主体,而管理员想要启用电子邮件,我想要显示一条消息,警告管理员该消息将不是他们习惯的完整表单,并联系开发以创建此主体。我想让这个工作在这样一种方式,我不需要更新我的代码,如果一个新的电子邮件正文,甚至一个新的表单完全被创建。

我想说明三种情况:

-Form_ABC_BA.getEmailBody(Form_ABC_BA)存在,因此覆盖FormsBA方法。

-Form_ABC_BA存在,但getEmailBody(Form_ABC_BA)不存在,因此FormsBA中的方法用于此表单

-Form_ABC_BA不存在,因此使用FormsBA中的方法

如何根据类名的字符串检查类是否覆盖了特定的方法

很难确切地说出您要解决的问题,但是有一种方法(假设您想找到一个具有给定名称的派生类,并且具有将相同派生类作为参数的静态方法):

var formName = String.Format("Form_{0}_BA", name);
var candidate = typeof(FormBA).Assembly
                              .GetTypes()
                              .Single(tt => tt.IsSubclassOf(typeof(FormBA))
                                         && tt.Name.EndsWith(formName));
var method = candidate.GetMethods(BindingFlags.Static | BindingFlags.Public)
                      .Single(mi => mi.GetParameters()
                                      .Single()
                                      .ParameterType == candidate);

如果我正确理解你的问题-那么你可以使用Type.GetMethod指定BindingFlags.DeclaredOnly。这将返回在您的特定类中明确声明的方法-如果这包括您的基方法,则特定类将覆盖您的基方法。您还可以检查方法是否是虚拟的,以确保它实际上覆盖了基类方法——以防止开发人员使用new关键字隐藏了原始方法,而不是覆盖它。

public bool IsOverridden(string methodName, Type baseType, Type specificType) 
{
    var baseMethod = baseType.GetMethod(methodName);
    var method = specificType.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);       
    return baseMethod != null && method != null && method.IsVirtual;
}

您只能判断一个类是否覆盖了一个虚方法。我假设您已经知道某个特定类型是否派生自另一个类型(否则使用runun的示例或使用Console.WriteLine(typeof (Base).IsAssignableFrom(typeof(Derived)))

)。

如果您想要查看特定类型是否声明(或覆盖一个虚拟)方法,您可以使用Type.GetMethods来搜索给定名称的方法。例如,如果您有一个名为"b2"的虚拟方法,您可以判断特定类型是否声明了该方法,如下所示:

typeof(MyType).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Any(m => m.Name == "b2")

我想我误解了你的问题。你不能用静态成员"扩展"任何东西。

我想你问的是你是否可以判断一个类是否有一个静态方法,它的参数是一个特定的类型。你可以通过迭代所有的方法,然后迭代所有的参数来寻找一个特定类型的参数。例如:

如果我想查看类型SomeType是否有接受类型FormType参数的方法,我可以这样做:

typeof(SomeType).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static).Any(m => m.GetParameters().Any(p=>typeof(FormType).IsAssignableFrom(p.ParameterType)))

有趣的问题。在OO术语中,您不想知道类如何处理请求。所以"知道"一个方法是否被覆盖并不重要。

现在是解决方案。如果知道一个方法是否被覆盖,你可以采取简单的方法:在基类中创建一个只读可重写的布尔属性,如"ismethodxoverrides",并将其设置为false。在重写该方法的类中,你也可以重写这个布尔值并将其设置为true。

public virtual class MyBaseClass
{
   public virtual boolean IsMethodXOverridden { get { return false; } }
   public virtual void MethodX()
   {
      DoSomething();
   }
}
public sealed class MySuperClass : MyBaseClass
{
   public override bool IsMethodXOverridden { get { return true; } }
   public override void MethodX()
   {
      DoSomethingElse();
   }
}