22

I frequently write C# code that has to use magic strings to express property names. 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.

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.

Does anyone know if there has ever been a feature consideration for C#/.NET to add compile-time reflection to overcome this pervasive problem?

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.

In addition, does anyone know of any potential issues with such a feature?

Thanks for the help.

MgSam
  • 12,139
  • 19
  • 64
  • 95
  • possible duplicate of [Using a lambda expression to avoid using a "magic string" to specify a property](http://stackoverflow.com/questions/3330758/using-a-lambda-expression-to-avoid-using-a-magic-string-to-specify-a-property) – Kirk Woll Feb 17 '12 at 20:45
  • 1
    Also see: [Get the property, as a string, from an Expression>](http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) – Kirk Woll Feb 17 '12 at 20:48
  • 3
    @KirkWoll This is not a duplicate of that question. The question's second paragraph indicates that MgSam is familiar with the expression tree technique; the question is whether there might be a new feature in the works that would allow a new solution to the problem. – phoog Feb 17 '12 at 20:52
  • @phoog, true. But this is *the* solution, as evidenced by this pattern's ubiquitous presence in the BCL. – Kirk Woll Feb 17 '12 at 20:55
  • Have you considered using an Inversion of Control container? They use a lot of reflection at the first instance of the application known as the composition root. The configuration is usually done in code or XML. – Travis J Feb 17 '12 at 20:56
  • Add it to the pile of 'potentially useful features in C# that probably won't get implemented because there are many more even more useful features to implement first'.... and move on. – James Gaunt Feb 17 '12 at 20:59
  • 2
    @KirkWoll but it's not particularly helpful to answer the question "is a better solution coming?" by saying "here's the existing solution." – phoog Feb 17 '12 at 21:12
  • related: http://stackoverflow.com/questions/795208/extracting-property-names-for-reflection-with-intellisense-and-compile-time-che http://stackoverflow.com/questions/4229597/why-not-a-memberinfo-reflection-function-for-c-sharp – nawfal Apr 02 '13 at 09:45
  • possible duplicate of [Why is there not a \`fieldof\` or \`methodof\` operator in C#?](http://stackoverflow.com/questions/1213862/why-is-there-not-a-fieldof-or-methodof-operator-in-c) – nawfal Apr 27 '13 at 13:09

4 Answers4

14

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.

Link to the design notes

No more reflection for information the compiler already knows at design time!

MgSam
  • 12,139
  • 19
  • 64
  • 95
14

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. 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? 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 .

Brad
  • 1,143
  • 9
  • 17
cynic
  • 5,305
  • 1
  • 24
  • 40
  • 1
    Well, it is a blog post from a C# language designer about real issues with implementing a "infoof()" operator that works like typeof but for any metadata (method, property etc.). OP asks the same questions as "User" from the article and the "User" gets all the answers. – cynic Feb 17 '12 at 20:56
  • 2
    Eric's answer seems to imply that using Expressions has solved the problem. But many of Microsoft's technologies use magic strings to represent classes/properties: ASP .NET (Web Forms and MVC), Silverlight, WPF, Winforms; they all use them. Not to mention 3rd party developers whose libraries you may rely on. And if you look hard enough you'll find core libraries that use them as well. To me this seems like a more pervasive issue (and one that's easier to address) than the issue that the async/await keywords solve. – MgSam Feb 17 '12 at 21:11
  • 1
    I don't think is post answers the why not for properties which are cannot be overloaded. – John Alexiou Apr 02 '13 at 12:39
  • 1
    While this answer is over a year old and the link is helpful it would be better if you post the essential parts of the answer here, on this site, or your post risks being deleted [See the FAQ where it mentions answers that are 'barely more than a link'.](http://stackoverflow.com/faq#deletion) You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link. – Taryn Oct 06 '14 at 11:24
7

I was having a similar problem. Only recently discovered that .NET Framework 4.5 has a feature called the Caller Info attributes. 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);
}
Kimi
  • 13,621
  • 9
  • 55
  • 84
0

Yet C#/.NET uses them all over the place to represent property/class/method names.

First off: I disagree. There are certain frameworks (WebForms, e.g.) that use magic strings all over the place, but the base libraries for C# and .NET tend to avoid such things remarkably well.

Secondly: In many instances where magic strings are used, ReSharper is able to recognize errors. 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."

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • 1
    I agree that core .NET libs stay away from the magic strings, but if you have looked at MVC3 at all, oh man, its MagicString hell :) Thank goodness for ReSharper's ability to tell you if you typed in a wrong controller or action name in a string parameter! – CodingWithSpike Feb 17 '12 at 21:02
  • 1
    The compiler already knows all of the relevant information during compile time to make this feature possible. From my understanding Roslyn will simply enable 3rd parties to more easily gain similar insights into the code before compile-time. – MgSam Feb 17 '12 at 21:14
  • 1
    @MgSam: Roslyn appears to make it possible to set up your own compilation rules, so it could conceivably allow you to write an expression tree in code that gets converted into a method name, controller name, etc. at compile time. – StriplingWarrior Feb 17 '12 at 21:36