将当前对象类型传递给基础构造函数调用
我如何获取inheritance类的Type
并将其传递给类inheritance的基类构造函数? 请参阅下面的代码示例:
// VeryBaseClass is in an external assembly public abstract class VeryBaseClass { public VeryBaseClass(string className, MyObject myObject) { } } // BaseClass and InheritedClass are in my assembly public abstract class BaseClass : VeryBaseClass { public BaseClass(MyObject myObject) : base(this.GetType().Name, myObject) // can't reference "this" (Type expected) { } } public class InheritedClass : BaseClass { public InheritedClass(MyObject myObject) { } }
行base(typeof(this).Name, myObject)
不起作用,因为我还不能引用this
,因为对象尚未完成构造,因此不存在。
是否可以获取当前构建对象的Type
?
编辑:
将样本更正为orsogufo建议 ,但仍然不起作用,因为this
是未定义的。
编辑2:
为了澄清,我想最终将"InheritedClass"
传递给VeryBaseClass(string className, MyObject myObject)
构造函数。
啊哈! 我找到了解决方案。 你可以用generics来做到这一点:
public abstract class VeryBaseClass { public VeryBaseClass(string className, MyObject myObject) { this.ClassName = className; } public string ClassName{ get; set; } } public abstract class BaseClass : VeryBaseClass { public BaseClass(MyObject myObject) : base(typeof(T).Name, myObject) { } } public class InheritedClass : BaseClass { public InheritedClass(MyObject myObject) : base(myObject) { } }
我之前在Google Wave Robot .NET API中遇到了同样的痛苦,我想让构造函数根据属性传递一些值。 您可以在代码中查看我的解决方案,以获取派生类型和基本类型 。 基本上我将委托传递给基础构造函数,然后调用该委托将“this”传递给委托。 所以在你的情况下,你有:
public VeryBaseClass(Func classNameProvider) { this.name = classNameProvider(this); }
和
public BaseClass() : base(FindClassName) { } private static string FindClassName(VeryBaseClass @this) { return @this.GetType().Name; }
这真的很难看,但它确实有效。
编辑:只有在您可以更改基类构造函数时,此方法才有效; 如果你不能,我不确定它实际上是否可行:(
GetType()。名称不起作用?
可能的解决方案:
class VeryBase { public VeryBase(string name) { Console.WriteLine(name); } } class Base : VeryBase where T : Base { protected Base() : base(typeof(T).Name) { } } class Derived : Base { public Derived() { } } class Program { public static void Main(params string[] args) { Derived d = new Derived(); } }
如果在运行时确定inheritance类的类型的能力比性能更重要,那么可以查看StackTrace以查看构造函数的调用位置。 在此示例中调用GetInheritedClassName时,您可能需要编写更多假设代码:
public abstract class BaseClass : VeryBaseClass { private static string GetInheritedClassName { get { // Get the current Stack StackTrace currentStack = new StackTrace(); MethodBase method = currentStack.GetFrame(1).GetMethod(); // 1st frame should be the constructor calling if (method.Name != ".ctor") return null; method = currentStack.GetFrame(2).GetMethod(); // 2nd frame should be the constructor of the inherited class if (method.Name != ".ctor") return null; // return the type of the inherited class return method.ReflectedType.Name; } } public BaseClass(MyObject myObject) : base(GetInheritedClassName, myObject) { } }
我想不出一个很好的方法来动态获取inheritance类的名称而不会影响性能。 我意识到你想要避免的,但如果我需要调用具有这些要求的第三方程序集,我只需要每个类指定自己的类型:
public abstract class BaseClass : VeryBaseClass { public BaseClass(string className, MyObject myObject) : base(className, myObject) { } } public class InheritedClass : BaseClass { public InheritedClass(MyObject myObject) : base("InheritedClass", myObject) { } }
又一个选择……
// VeryBaseClass is in an external assembly public abstract class VeryBaseClass { public VeryBaseClass(string className) { Console.WriteLine(className); } } // BaseClass and InheritedClass are in my assembly public abstract class BaseClass : VeryBaseClass { public BaseClass(string className) : base(className) { } } public class InheritedClass : BaseClass { public InheritedClass() : base(typeof(InheritedClass).Name) { } }