确定 C# 方法是否具有关键字“override”使用反射
我原以为这个问题能轻松找到答案,但我没有。 我想知道是否可以根据给定的 MethodInfo
实例来确定某个方法是否具有关键字“override”。
我在想也许以下内容可以实现这一点:
/// <summary> Returns whether the specified methodInfo is attributed with the keyword 'override'. </summary>
public static bool IsOverriding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException();
return methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;
}
我已经成功测试了一些非虚拟、虚拟和抽象的示例,但我觉得我错过了一些场景,可能是隐藏或泛型(尽管我不知道如何这将会发挥作用)。
I had expected to find an answer easily to this problem, but I didn't.
I'd like to know if it is possible to determine whether a method has the keyword 'override' attributed to it, given its instance of MethodInfo
.
I was thinking maybe the following would achieve that:
/// <summary> Returns whether the specified methodInfo is attributed with the keyword 'override'. </summary>
public static bool IsOverriding(this MethodInfo methodInfo)
{
if (methodInfo == null) throw new ArgumentNullException();
return methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType;
}
I've sucessfully tested some non-virtual, virtual and abstract examples, but I feel like I'm missing some scenarios, maybe with hiding or generics(although I can't figure out how that would come into play).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我也试图找到这个东西。从问题中,您给出了让
IsOverriding
为override
关键字工作的想法。但是,为了隐藏,我尝试为关键字new
创建IsHiding
。以下是基本的 C# OOP:override
仅在基于方法包含abstract
或virtual
修饰符时使用。new
用于隐藏具有相同名称的基方法,但是...new
不能应用于abstract
基方法,因为它会生成编译器错误。virtual
,new
也可以应用于方法。插入的部分是我们可以隐藏或重写
virtual
方法。我们知道,如果我们覆盖
一个虚拟
方法,GetBaseDefinition()
将返回基本的MethodInfo
。但区分它的关键是,如果我们隐藏virtual<,
GetBaseDefinition()
将返回相同的MethodInfo
而不是基本MethodInfo
/代码> 方法。override
关键字是必须的,而new
仅用于抑制警告消息。因此我们可以通过将IsAbstract
和IsVirtual
与DeclaringType
结合来区分override
和new
和BaseType
。我使用简单的继承对其进行了测试,并且它有效。我还没有考虑泛型方法..
编辑:我只是更改了上面的代码,因为我忘记了继承类型可以包含新声明的方法的想法,该方法不应该被视为新方法。
IsHiding()
首先确保它具有相同的DeclaringType
(看起来像新的),但需要通过DeclaringType.BaseType 如果存在同名方法。
请注意,由于没有
BindingFlags.DeclaredOnly
,GetMethod()
将搜索整个基类型,因此无需递归搜索每个基类型。BindingFlags.FlattenHierarchy
用于在抽象-抽象基类中包含静态方法,如下所示:编辑:我只是将上面的
IsHiding()
修复为使用GetMethods()
而不是GetMethod()
检查基本方法重载并防止AmbigouslyMatchException
。重载经过测试可与不同参数组合使用,与ref
、out
、params
和可选参数混合使用。根据参数计数、参数类型及其修饰符进行比较的重载签名:ref
或out
,但两者不能互相重载。返回类型、可选(默认值)和最右边参数的
params
与ParameterType
本身相比,ref
(请参阅结尾的 '& ;' 在调试期间)并且不需要通过IsByRef
进行比较,而out
通过Attributes
标志进行比较。当且仅当其中一个属性具有使签名不同的标志Out
时,我使用简化表达式按位 XOR 来跳过循环。不要与.NET 4中的HasFlag
混淆,它只是想通过XOR结果确保Out
位为1。I try to find this thing also. From the question, you give the idea to get
IsOverriding
work foroverride
keyword. However for hiding I try to createIsHiding
for keywordnew
. Here is the basic C# OOP:override
only used when the based method containabstract
orvirtual
modifier.new
is used to hide based method with the same name but...new
cannot be apply toabstract
base method because it generate compiler error.new
also can be applied to method if the base method containvirtual
.The inseresting part is we can hide or override
virtual
method. We know thatGetBaseDefinition()
will return the baseMethodInfo
if weoverride
avirtual
method. but the key to differentiate it is theGetBaseDefinition()
will return the sameMethodInfo
instead of it baseMethodInfo
if we hidingvirtual
method.override
keyword is a must whilenew
is only used to suppress the warning message. So we can diffrentiateoverride
andnew
by theIsAbstract
andIsVirtual
combine withDeclaringType
andBaseType
.I test it using the simple inheritance and it works. I don't think about generic method..yet..
EDIT: I just change the code above because I forgot the idea about inherited type can contain newly declared method which is should not threated as new.
IsHiding()
will first make sure it have the sameDeclaringType
(it seems like new) but need to look at the base declaring types byDeclaringType.BaseType
if a method with the same name exist.Note that because of there is no
BindingFlags.DeclaredOnly
,GetMethod()
will search through the entire base types, so no need to recursively search to each base types.BindingFlags.FlattenHierarchy
is used to include static method in abstract-abstract base class like this:EDIT: I just fix the
IsHiding()
above to check for base method overloads and preventAmbiguousMatchException
by usingGetMethods()
instead ofGetMethod()
. The overloads tested to work with combination with different parameters, mix withref
,out
,params
and optional parameter. Signature for overloads being compared based on parameter count, parameter types and its modifier:ref
orout
included in the signature but both cannot be overloaded to each other.params
on right most parameter should be ignoredref
compared by theParameterType
itself (see the ending '&' during debugging) and no need to compare by theIsByRef
while theout
compared by theAttributes
flag. I am using simplified expression bitwise XOR to skip the loop if and only if one of the attributes has flagOut
which makes the signature different. Don't confused withHasFlag
in .NET 4, it just want to make sureOut
bit is 1 by the XOR result.好吧,我也不明白这会如何发挥作用。您的代码确实确定了是否定义或重写了方法。
在隐藏的情况下,声明类型是通过
new
隐藏方法的类型。对于泛型,所有方法都由模板类定义。
Well, I don't see how that would come into play either. Your code there does indeed determine whether a method is defined or overriden.
In the case of hiding, the declaring type is the one that hides the method via
new
.In the case of generics, all methods are defined by the template class.
你可以试试这个
You can try this