简体   繁体   English

在C#中编译时间反射

[英]Compile Time Reflection in C#

I frequently write C# code that has to use magic strings to express property names. 我经常编写C#代码,必须使用魔术字符串来表达属性名称。 Everyone knows the problems with magic strings. 每个人都知道魔术弦的问题。 They are very difficult to refactor, they have no compile time checking, and often they lead to hard-to-diagnose issues. 它们很难重构,它们没有编译时检查,并且通常会导致难以诊断的问题。 Yet C#/.NET uses them all over the place to represent property/class/method names. 然而,C#/ .NET 在整个地方使用它们来表示属性/类/方法名称。

This issue has persisted for years and years, and the only viable solution currently is to use an expression tree which is then parsed at run-time for the property name. 这个问题已持续多年和多年,目前唯一可行的解​​决方案是使用表达式树,然后在运行时解析属性名称。 This gets you satisfactory compile-time checking, but it complicates the code (requiring parameters of type Expression), and it incurs a run-time cost. 这使您获得令人满意的编译时检查,但它使代码复杂化(需要Expression类型的参数), 并且会产生运行时成本。

Does anyone know if there has ever been a feature consideration for C#/.NET to add compile-time reflection to overcome this pervasive problem? 有没有人知道是否有一个特性考虑因为C#/ .NET添加编译时反射来克服这个普遍存在的问题?

It seems like it would be an easy addition to make, it would be a non-breaking change, and it would greatly benefit many developers. 看起来这将是一个简单的补充,它将是一个非破坏性的变化,它将使许多开发人员受益匪浅。 The typeof() operator already performs a form of compile-time reflection, so it seems like an operator nameof() (or something similar) would be very complimentary. typeof()运算符已经执行了编译时反射的形式,因此看起来运算符nameof()(或类似的东西)将非常互补。

In addition, does anyone know of any potential issues with such a feature? 此外,有没有人知道这个功能的任何潜在问题?

Thanks for the help. 谢谢您的帮助。

In C# 6.0, a new operator, nameof , is being added that will allow you to get the names of properties, classes, fields, events, and variables at compile time. 在C#6.0中,添加了一个新的运算符nameof ,它允许您在编译时获取属性,类,字段,事件和变量的名称。

Link to the design notes 链接到设计说明

No more reflection for information the compiler already knows at design time! 不再反映编译器在设计时已经知道的信息!

Straight from the source - this is a blog post by a C# language designer, and the "User" in this post asks about the same questions as you and is answered. 直接来源 - 这是C#语言设计师的博客文章,这篇文章中的“用户”询问与您相同的问题并得到解答。 The author says there would be a need to specify a syntax for every metadata item you'd want to ask for and it's not trivial - ie. 作者说,需要为你想要求的每个元数据项指定一个语法,这不是一件容易的事 - 即。 which overload you want, if you want "info-of" method and the method is overloaded? 你想要哪个超载,如果你想要“info-of”方法并且方法被重载了? What if there are generics and explicit interface implementations involved? 如果涉及泛型和显式接口实现会怎样? And so on. 等等。 It turns out, while it wasn't deemed worthy of implementation in 2009 because of those reasons, we will get it in C# 6 in 2015 - see C# Language Design Notes for Jul 9, 2014 . 事实证明,虽然由于这些原因在2009年被认为不值得实施,但我们将在2015年的C#6中获得它 - 请参阅2014年7月9日的C#语言设计说明

I was having a similar problem. 我遇到了类似的问题。 Only recently discovered that .NET Framework 4.5 has a feature called the Caller Info attributes. 最近才发现.NET Framework 4.5具有一个名为Caller Info属性的功能。 By using these, you can obtain information about the caller to a method at compile time. 通过使用这些,您可以在编译时获取有关调用方的信息。 You can obtain file path of the source code, the line number in the source code, and the member name of the caller. 您可以获取源代码的文件路径,源代码中的行号以及调用者的成员名称。

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}

Yet C#/.NET uses them all over the place to represent property/class/method names. 然而,C#/ .NET在整个地方使用它们来表示属性/类/方法名称。

First off: I disagree. 首先:我不同意。 There are certain frameworks (WebForms, eg) that use magic strings all over the place, but the base libraries for C# and .NET tend to avoid such things remarkably well. 有一些框架(WebForms,例如)在整个地方使用魔术字符串,但C#和.NET的基础库往往会非常好地避免这种情况。

Secondly: In many instances where magic strings are used, ReSharper is able to recognize errors. 其次:在使用魔术字符串的许多情况下,ReSharper能够识别错误。 This can help quite a bit. 这可以帮助很多。

Finally: What you're asking for may be possible via the Roslyn Compiler, which promises to provide "Compiling as a service." 最后:您可以通过Roslyn编译器提出要求,该编译器承诺提供“编译即服务”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM