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

时间:2011-07-11 19:42:30

标签: c# .net

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

值得注意的一些事情:

  • 并非所有表单都有Form_XXXX_BA,但如果添加了代码,我想编辑我的代码。
  • 我正在检查的方法是静态的,但是,它需要Form_XXXX_BA类作为参数。

我看过Activator.CreateInstanceSystem.Reflection,但我无法理解他们会如何提供帮助(虽然他们可能会有很好的解决方案,但我不是了解他们)。

编辑:是的,通过扩展一个方法,我的意思是覆盖,我的坏。固定的。

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

我在系统上有很多表单。对于某些表单,用户可以将它们发送给另一个用户。目前,所有表单都有一个默认消息(FormsBA.getEmailBody(FormsBA))。当前可发送的方法会覆盖此方法,因此请根据表单本身设置正文。 (例如,表格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中的方法

4 个答案:

答案 0 :(得分:1)

很难确切地告诉你要解决的是什么,但是有一种方法(假设你想要找到一个具有给定名称的派生类,该类具有静态方法,将相同的派生类作为参数):

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);

答案 1 :(得分:1)

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

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;
}

答案 2 :(得分:0)

您只能判断某个类是否覆盖虚拟方法。我假设您已经知道特定类型是否来自另一个(其他使用重新运行的示例或使用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)))

答案 3 :(得分:0)

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

现在寻求解决方案。如果知道方法是否被覆盖,您可以采取简单的方法: 在基类中创建一个只读的可覆盖布尔属性,如“IsMethodXOverriden”,并将其设置为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();
   }
}