如何根据类名的字符串检查类是否覆盖了特定的方法
本文关键字:覆盖 方法 是否 字符串 何根 检查 | 更新日期: 2023-09-27 18:01:42
我有一个基类叫做FormBA。有几个类根据Form_XXXX_BA
的命名方案扩展了这个类(其中XXXX
是表单的缩写名称)。给定表单的缩写名,我需要检查它是否覆盖了一个特定的方法(如果需要,我可以根据方法的输出来判断)
值得注意的事情:
- 不是所有的形式都有一个
Form_XXXX_BA
,但我想要编辑我的代码,如果一个添加。 - 我检查的方法是静态的,但是,它需要一个
Form_XXXX_BA
类作为参数。
我已经看过Activator.CreateInstance
和System.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();
}
}