Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何根据类名的字符串检查类是否重写了特定的方法?_C#_.net - Fatal编程技术网

C# 如何根据类名的字符串检查类是否重写了特定的方法?

C# 如何根据类名的字符串检查类是否重写了特定的方法?,c#,.net,C#,.net,我有一个基类叫FormBA。有几个类按照表单_XXXX_BA的名称方案扩展了该类(其中XXXX是表单的缩写名称)。给定表单的缩写名称,我需要检查它是否覆盖了一个特定的方法(如果需要,我可以根据方法的输出来判断) 一些值得注意的事情: 并非所有表单都有表单_XXXX_BA,但如果添加了一个,我希望必须编辑我的代码 我正在检查的方法是静态的,但是,它将Form\u XXXX\u BA类作为参数 我已经看过了Activator.CreateInstance和System.Reflection,但我

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

一些值得注意的事情:

  • 并非所有表单都有
    表单_XXXX_BA
    ,但如果添加了一个,我希望必须编辑我的代码
  • 我正在检查的方法是静态的,但是,它将
    Form\u XXXX\u BA
    类作为参数
我已经看过了
Activator.CreateInstance
System.Reflection
,但我还没有弄清楚它们会有什么帮助(虽然它们可能是不同的解决方案,但我就是不理解它们)

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

感谢您迄今为止的帮助,很抱歉,我不清楚我的问题,尽管看起来sixlettervariables可能在正确的轨道上

我在系统上有很多表格。对于某些表单,用户可以通过电子邮件将其发送给其他用户。目前,所有表单都有一条默认消息(FormsBA.getEmailBody(FormsBA))。当前可发送的将覆盖此方法,因此基于表单本身设置正文。(例如,对于表单ABC-Form_ABC_BA.getEmailBody(Form_ABC_BA))

现在的问题是,现在有一个管理面板,可以为每个单独的表单启用/禁用电子邮件发送。如果表单没有此自定义正文,并且管理员希望启用电子邮件发送,我希望显示一条消息,警告管理员消息将不是他们习惯的完整表单,并与开发部门联系以创建此正文。我想这样做的方式,我不必更新我的代码,如果一个新的电子邮件正文,甚至是一个新的表单创建

我想解释三种情况:

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

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


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

很难准确地说出您试图解决的问题,但有一种方法(假设您希望找到一个具有给定名称的派生类,该派生类具有一个静态方法,该方法将同一派生类作为参数):


您只能判断类是否重写了虚拟方法。我假设您已经知道某个特定类型是否从另一个派生(其他人使用rerun的示例或使用
Console.WriteLine(typeof(Base).IsAssignableFrom(typeof(派生)))

如果要查看特定类型是否声明(或重写虚拟)方法,可以使用
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)))

如果我正确理解了您的问题,那么您可以使用specifying。这将返回在您的特定类中专门声明的方法。如果这包括您的基本方法,那么指定类将覆盖您的基本方法。您还可以检查该方法是否为虚方法,以确保它实际覆盖基本类ss方法-防止开发人员使用
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;
}

有趣的问题。用面向对象的术语来说,你们不想知道一个类如何处理一个请求。所以“知道”一个方法是否被重写并不重要

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

“扩展方法”是指“重写方法”吗?这是一个有趣的问题。你能给出一些代码示例吗?我不确定我是否100%不知道你在问什么。你能解释一下为什么你想知道这个吗?给定的类是否选择重写虚拟方法通常被认为是该类的一个实现细节;你通常不会用它来做决定关于方法的操作。如果你正在编写调试工具,这是一回事。如果你正在编写业务逻辑,我建议你描述真正的问题,看看是否有更好的解决方案。如果出现一个退出表单,并且由于不同的原因而重写了此方法,会发生什么情况。你需要能够告诉我吗区别。这会对您的系统产生什么影响?
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();
   }
}