我对某些东西感到有些困惑,我希望CLR减速机可以提供帮助。显然我的齿轮不够大。
我有一个反射器实用程序,它为Cola for .NET生成程序集存根,我发现类的方法只有一个修饰符不同,例如virtual。以下示例,来自Oracle.DataAccess.dll,方法GetType():
class OracleTypeException : System.SystemException {
virtual string ToString ();
virtual System.Exception GetBaseException ();
virtual void set_Source (string value);
virtual void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context);
virtual System.Type GetType (); // DeclaringType Exception
virtual bool Equals (object obj);
virtual int32 GetHashCode ();
System.Type GetType (); // DeclaringType Object
}
这是什么?
我无法使用C#重现这一点,因为它认为GetType()是重新定义,因此可能会给Cola带来麻烦,因为签名是相同的。
我的方法反射器就像这样开始:
static void DisplayMethod(MethodInfo m)
{
if (
// Filter out things Cola cannot yet import, like generics, pointers, etc.
m.IsGenericMethodDefinition || m.ContainsGenericParameters || m.ReturnType.IsGenericType
|| !m.ReturnType.IsPublic
|| m.ReturnType.IsPointer || m.ReturnType.IsByRef
|| m.ReturnType.IsMarshalByRef
|| m.ReturnType.IsImport
)
return;
// generate stub signature
// [snipped]
}
解决: 非虚拟GetType()来自System.Object。派生类使用虚方法阴影化System.Object.GetType()。
答案 0 :(得分:3)
我会检查:
请注意,您也可以重新声明方法,这可能是一个因素;但那会很疯狂;但是,这表明了这一点:
class Bar {
new Type GetType() { return null; }
}
static class Program {
static void Main() {
var methods = typeof(Bar).GetMethods(
BindingFlags.Instance | BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic);
foreach (var method in methods) {
Console.WriteLine(method.Name);
}
}
}
答案 1 :(得分:3)
这是可能的。这是一个编译得很好的代码片段:
public class OracleTypeException : SystemException, _Exception
{
public virtual Type GetType()
{
throw new NotImplementedException();
}
Type _Exception.GetType()
{
throw new NotImplementedException();
}
}
它依赖于SystemException实现_Exception的事实,GetType本身定义了an explicit implementation方法。所以我们有:
顺便说一句,编译器会生成一个关于它的警告。
答案 2 :(得分:1)
此类应表现出相同的行为:
class Something {
public virtual Type GetType() {
throw new NotImplementedException();
}
}
由于每个类都继承自System.Object,因此它还继承了非虚拟 Object.GetType()方法。将方法重新声明为虚拟(请注意,甚至不需要“new”关键字)隐藏原始继承的GetType方法。
不确定这个工具需要什么,但我想你需要用“Object_GetType”重命名隐藏的继承方法。