提问人:Denis G. Labrecque 提问时间:8/25/2022 最后编辑:Denis G. Labrecque 更新时间:8/25/2022 访问量:839
一般获取当前类的名称?
Generically get the name of the current class?
问:
记录数据时,我想要对包含类的泛型引用。这样,如果将代码移动到其他位置,类名将相应更改。(否则,如果代码移动到 ,它仍将被错误地记录为 )。例如:nameof(Class2)
nameof(Class1)
class Class_Name {
ICommand Command_Name =>
new RelayCommand(() =>
{
// An loggable event occurs
// Is there a smart and uncomplicated way of doing this generically?
var provenance = $"{nameof(Class_Name)}.{nameof(Command_Name)}";
// The event of whatever kind gets logged
});
}
// OR
void Method_Name() {
var provenance = $"{nameof(Class_Name)}.{nameof(Method_Name)}";
}
}
使用泛型 ,其中应引用类本身,会导致编译错误: CS8081: 表达式没有名称。使用会导致同样的问题。nameof(this)
this
this.GetType()
不真正理解为什么关键字在此上下文中不引用包含类。有没有办法笼统地引用当前类?this
答:
2赞
mcjmzn
8/25/2022
#1
nameof 表达式在编译时计算,在 运行时间。
若要动态访问类型,可以在运行时中使用该方法。只是记得不要将它与 .GetType
nameof
class Class_Name {
void Method_Name() {
// An event occurs
// Is there a smart and uncomplicated way of doing this generically?
var provenance = $"{this.GetType().Name}.{MethodBase.GetCurrentMethod().Name}";
// The event of whatever kind gets logged
}
}
评论
0赞
Jeppe Stig Nielsen
8/25/2022
如果使用 或 只是,则它不等同于,因为该类未标记为 .(这假定在具有基类的类的实例上调用私有方法。$"{this.GetType().Name}"
$"{GetType().Name}"
nameof(Class_Name)
sealed
Class_Name
0赞
Denis G. Labrecque
8/25/2022
@JeppeStigNielsen 为什么继承类的实例的类型名称与 不同,实例的类型在哪里?nameof(Class_Name)
Class_Name
1赞
Jeppe Stig Nielsen
8/25/2022
@DenisG.Labrecque 我试着做一个.NET小提琴来解释我的意思:在这里试试吧!如果更改为 ,则输出会有所不同。nameof(Class_Name)
0赞
Denis G. Labrecque
8/25/2022
@JeppeStigNielsen感谢您的投入;确实,在调用发生在基方法中的情况下,让子类的名称代表基会造成混淆。
4赞
David L
8/25/2022
#2
如果通过帮助程序方法将注释中的建议与属性相结合,则可以以可重用的方式完成所需的任务。this.GetType().Name)
[CallerMemberName]
public class Class_Name
{
public void Method_Name()
{
var provenance = CreateProvenance();
Console.WriteLine(provenance);
}
private string CreateProvenance([CallerMemberName] string methodName = "")
{
return $"{this.GetType().Name}.{methodName}";
}
}
这将输出“Class_Name.Method_Name”。
您甚至可以将其转换为方便的扩展方法,允许您从任何方法调用它。
public class Class_Name
{
public void Method_Name()
{
var provenance = this.CreateProvenance();
Console.WriteLine(provenance);
}
}
public static class ProvenanceExtensions
{
public static string CreateProvenance(this object context,
[CallerMemberName] string methodName = "")
{
return $"{context.GetType().Name}.{methodName}";
}
}
正如 Jeppe Stig Nielsen 所指出的,您可能不希望使用继承的运行时类型,而继承运行时类型将返回。如果要改为获取编译时类型,可以使用泛型。context.GetType().Name
public static class ProvenanceExtensions
{
public static string CreateProvenance<T>(this T context,
[CallerMemberName] string methodName = "")
{
return $"{typeof(T).Name}.{methodName}";
}
}
评论
1赞
Jeppe Stig Nielsen
8/25/2022
与我对 mcjmzn 的答案的评论相关,给出的是运行时类型,而不是编译时类型。另一种选择可能是:但是,您想要两种行为中的哪一种取决于您。context.GetType()
public static string CreateProvenance<TCompileType>(this TCompileType context, [CallerMemberName] string methodName = "") { return $"{typeof(TCompileType).Name}.{methodName}"; }
1赞
David L
8/25/2022
这是一个很好的标注,在我的回答中非常有意义。我将更新它以记录两者,具体取决于 OP 正在寻找的行为。
评论
$"{nameof(this.GetType())}"
$"{this.GetType().Name}"
this.GetType()
this
nameof()
ICommand
nameof
this.GetType()
this.GetType().Name