正如标题所示,可以确定实例化另一个类的特定实例的类的哪个实例?
更新:下面的示例代码
class FooBar: Foo
{
private Context context;
public FooBar(Context _context): base(_context)
{
this.context = _context;
}
}
class Foo
{
public Baz baz;
private Context context;
public Foo(Context _context)
{
baz = new Baz();
this.context = _context;
}
}
class Baz
{
public Baz()
{
GetNameOfCaller()
}
private void GetNameOfCaller()
{
....
....
_className = ....;
}
private string _className;
}
答案 0 :(得分:7)
是的,您可以像常规方法一样为构造函数执行此操作。只需使用CallerMemberName
传递调用方法的名称即可。你不会有它的类名,那么你需要走StackTrace
这更复杂。
public class X
{
public X([CallerMemberName] string caller = null)
{
this.Caller = caller;
}
public string Caller { get; private set; }
}
然后就这样打电话。编译器将为您填写caller
参数:
static void Main(string[] args)
{
X x = new X();
Console.WriteLine($"Caller = {x.Caller}"); // prints Main
}
答案 1 :(得分:4)
您可以使用System.Diagnostics.StackTrace
:
public class Foo
{
public void MethodBah()
{
System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();
MethodBase callingMethod = t.GetFrame(1).GetMethod();
Type callingMethodType = callingMethod.DeclaringType;
string className = callingMethodType.Name;
}
}
即使在.NET 1.1中也能正常工作。
使用您的(已更新)示例,您必须使用t.GetFrame(2).GetMethod()
代替GetFrame(1)
来获取FooBar
而不是Foo
,因为子调用父构造函数。
答案 2 :(得分:2)
我相信您的要求应该使用aspect-oriented programming来解决。
OP在一些评论中表示:[..]现在记录目的但可能不仅限于它[...]
例如,有一个非常强大的工具叫PostSharp,它可以让你拦截任何方法调用,当它被调用时和调用之后:
[Serializable]
public class LogAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
}
public override void OnExit(MethodExecutionArgs args)
{
}
}
现在,您可以将整个方面作为常规属性应用于方法,类或甚至应用于程序集(因此,程序集中的所有方法都将 loggable )。
您可以通过MethodExecutionArgs.Method
(类型为MethodBase
)访问被调用的方法,这意味着您可以访问哪种类型通过MethodBase.DeclaringType
声明整个方法。
使用像PostSharp这样的工具,您可以添加额外的编译步骤,但它具有在编译时注入拦截的巨大优势。也就是说,它会像在每种方法中手动添加整个代码一样。
您还可以使用Castle DynamicProxy创建运行时代理来拦截方法调用。