Source code for the "nameof" operator of C# - c#

Where can I get the source code for "nameof" of C# or how do I decompile it?
I checked https://referencesource.microsoft.com/, but I couldn't find it.

It's not something you can decompile as such, or show you source code for. It's part of the C# compiler: when you use nameof(Foo) the compiler just injects "Foo" into the source code. The IL for the methods is exactly the same:
static void PrintMyName()
{
Console.WriteLine(nameof(PrintMyName));
}
vs
static void PrintMyName()
{
Console.WriteLine("PrintMyName");
}
As noted in comments, it's not just that the name is taken literally as per the operand; it's the last part of the name that's used. So for example, if you have:
string x = "10";
string text = nameof(x.Length);
then that will resolve to "Length". (This doesn't use the value of x at execution time, either - it's fine if x is null. Or you could use nameof(string.Length) or nameof(String.Length).)

nameof is a keyword, so you would need to look into the compiler for the source code of how it is processed. Fortunately for you, the C# compiler is now open-sourced under the Roslyn project. Understanding a compiler is not a trivial task – source code is passed through pipelines of transformations, which each one adding more syntactic or semantic information. To start you off, the GetContextualKeywordKind parses the nameof keyword into a SyntaxKind.NameOfKeyword, which then gets matched in TryBindNameofOperator.
As to your other question of creating another such operator: Yes, you can, by cloning and modifying the Roslyn source. However, your new operator would obviously only work on the modified compiler, so you'd need to supply this to whoever will be compiling your code. This is something that's rarely done; you're normally better off defining extension methods for your custom functionality, unless you need something particularly esoteric.

Related

How to translate or convert CompilerGenerated code?

If you try to use decompilers like: jetbrains dotpeek, redgate reflector, telerik justdecompile, whatever.. Sometimes if you need a code to copy or just to understand, it is not possible because are shown somethings like it:
[CompilerGenerated]
private sealed class Class15
{
// Fields
public Class11.Class12 CS$<>8__locals25;
public string endName;
// Methods
public Class15();
public bool <Show>b__11(object intelliListItem_0);
}
I'm not taking about obfuscation, this is happens at any time, I didsome tests (my own code), and occurs using lambdas and iterators. I'm not sure, could anyone give more information about when and why..?
So, by standard Visual Studio not compile $ and <> keywords in c# (like the code above)...
There is a way to translate or convert this decompiled code automatically?
Lambdas are a form of closure which is a posh way of saying it's a unit of code you can pass around like it was an object (but with access to its original context). When the compiler finds a lambda it generates a new type (Type being a class or struct) which encapsulates the code and any fields accessed by the lambda in its original context.
The problem here is, how do you generate code which will never conflict with user written code?
The compiler's answer is to generate code which is illegal in the language you are using, but legal in IL. IL is "Intermediate Language" it's the native language used by the Common Language Runtime. Any language which runs on the CLR (C#, vb.net, F#) compiles into IL. This is how you get to use VB.Net assemblies in C# code and so on.
So this is why the decompilers generate the hideous code you see. Iterators follow the exact same model as do a bunch of other language features that require generated types.
There is an interesting side effect. The Lambda may capture a variable in its original context:
public void TestCapture()
{
StringBuilder b = new StringBuilder();
Action l = () => b.Append("Kitties!");
}
So by capture I mean the variable b here is included in the package that defines the closure.
The compiler tries to be efficient and create as few types as possible, so you can end up with one generated class that supports all the lambdas found in a specific class, including fields for all the captured variables. In this way, if you're not careful, you can accidentally capture something you expect to be released, causing really tricky to trace memory leaks.
Is there an option to change the target framework?... I know with some decompilers they default to the lowest level framework (C# 1.0)

Method analysis using Reflection and CodeDom

The context of this question is too elaborate to describe here and will likely adversely affect responses so I am not including it. I want to assert certain things about a method in a unit test. Some of these things are possible using reflection such as format of the try/finally block, class fields and method local variables, etc. I already know the type and method signature.
protected override void OnTest ()
{
bool result = false;
SomeCOMObject com = null; // System.__ComObject
try
{
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
}
return (result);
}
What I have not been able to achieve are things like:
Whether the method contains only a single return (result); statement and whether that statement is the last one in the function.
Whether all variables of type System.__ComObject have been manually de-referenced using System.Runtime.InteropServices.Marshal.ReleaseComObject(object) in the finally block.
Since some of these things are not possible using reflection, and source code text analysis is far from ideal, I turned to CodeDom but have not been able to get a grip on it. I have been told that creating expression trees from source code is not possible. Nor is it possible to create expression trees from the runtime type. If that is correct, how can I leverage CodeDom to achieve things in the list above?
I have used CodeDom in the past for code generation and compiling simple code classes to assemblies. But I have no idea how it could be used to analyze the internals of a method. Please advise.
In general, reflection built into programming languages provides no access to the content of functions. So you pretty much can't do this with reflection.
You might be able to do it if you have access to the byte-code equivalent, but byte code can't really answer questions about the syntax of the method, e.g., "how many return statements exists returning the same expression".
If you want to reason about code, your need to reason about the source code. This means you need access to a parser, and often other useful facts ("what the declaration of X?", "Is the type of X and Y compatible?", "Does data flow from X to Y?"), etc.
Roslyn provides some of this information. There are also commercial solutions (I have one).

Property / Method inlining and impact on Reflection

My answer to one of the question on SO was commented by Valentin Kuzub, who argues that inlining a property by JIT compiler will cause the reflection to stop working.
The case is as follows:
class Foo
{
public string Bar { get; set; }
public void Fuzz<T>(Expression<Func<T>> lambda)
{
}
}
Fuzz(x => x.Bar);
Fuzz function accepts a lambda expression and uses reflection to find the property. It is a common practice in MVC in HtmlHelper extensions.
I don't think that the reflection will stop working even if the Bar property gets inlined, as it is a call to Bar that will be inlined and typeof(Foo).GetProperty("Bar") will still return a valid PropertyInfo.
Could you confirm this please or my understanding of method inlining is wrong?
JIT compiler operates at runtime and it can't rewrite metadata information stored in the assembly. And reflection reads assembly to access this metadata. So there are no impact from JIT-compiler to reflection.
EDIT:
Actually there are couple of places when C# compiler itself "inlines" some information during compilation. For example, constants, enums and default arguments are "inlined" so you can't access them during reflection. But it definitely not related to your particular case.
Yeah when I think about it more I guess only way inlining properties could fail INotifyPropertyChanged interface correct work would be if you were using a reflection based method used like
public Count
{
get {return m_Count;}
set { m_Count=value;
GetCurrentPropertyNameUsingReflectionAndNotifyItChanged();}
}
If used like you suggest indeed metadata exists in assembly and property name will be successfully taken from there.
Got us both thinking though.
I personally agree with #Sergey:
Considering that inlining happens on JIT compiler side, but metadata generated before, it shouldn't inpact on reflection in any way. By the way, good question, like it +1
Expression trees can't be in-lined anyway since they are a representation of the expression (abstract syntax tree) rather than the expression itself.
Delegates, even if they can be in-lined, will still carry the data about the method and target being called in their properties.

Automatically exchange explicit type with var-keyword

I want to automatically remove all explicit types and exchange them with the var keyword in a big solution, e.g. instead of
int a = 1;
I want to have:
var a = 1;
This is just cosmetics, the code in the solution works perfectly fine, I just want to have things consistent, as I started out using explicit types, but later on used var-keywords.
I'm guessing I would have to write some sort of code parser - sounds a little cumbersome. Does anybody know an easy solution to this?
Cheers,
Chris
This isn't an answer per se, but it's too long for a comment.
You should strongly consider not doing this. There's no stylistic concern with mixing explicit and inferential typing (you should infer types when you need to, either when using anonymous types or when it makes the code easier to read), and there are plenty of potential issues you'll encounter with this:
Declarations without assignment are ineligible
Declarations that are assigned to null are ineligible
Declarations that are of a supertype but initialized to an instance of a subtype (or compatible but different type) would change their meaning.
I.E.
object foo = "test";
...
foo = 2;
Obviously, this is a simple (and unlikely) example, but changing foo from object to var would result in foo being typed as a string instead of object, and would change the semantics of the code (it wouldn't even compile in this case, but you could easily run into more difficult to find scenarios where it changes overload resolution but doesn't produce a compile-time error).
In other words, don't do this, please.
Firstly, this is probably not such a good idea. There is no advantage to var over int; many declarations will be almost as simple.
But if you must...
A partly manual solution is to turn ReSharper's "Use var" hint into a warning and get it to fix them all up. I don't know if ReSharper will do it en masse, but I often rifle through a badly-done piece of third-party code with a rapid sequence of Alt+PgDn, Alt+Enter.
This has the significant advantage that ReSharper respects the semantics of your code. It won't replace types indiscriminately, and I'm pretty sure it will only make changes that don't affect the meaning of your program. E.g.: It won't replace object o = "hello"; (I think; I'm not in front of VS to check this).
Look into Lex & Yacc. You could combine that with a perl or awk script to mechanically edit your source.
You could also do this in emacs, using CEDET. It parses code modules and produces a table of its code analysis.
In either case you will need to come up with an analysis of the code that describes... class declarations (class name, parent types, start and end points), method declarations (similar), variable declarations, and so on. Then you will write some code (perl, awk, powershell, elisp, whatever) that walks the table, and does the replace on each appropriate variable declaration.
I'd be wary of doing this in an automated fashion. There are places where this may actually change the semantics of the program or introduce errors. For example,
IEnumerable<string> list = MethodThatReturnsListType();
or
string foo = null;
if (!dict.TryGetValue( "bar", out foo ))
{
foo = "default";
}
Since these aren't errors, I would simply replace them as you touch the code for other reasons. That way you can inspect the surrounding code and make sure you aren't changing the semantics and avoid introducing errors that need to be fixed.
What's about search/replace in Visual Studio IDE
For example search vor 'int ' and replace it with 'var '.

Contracts in C# 4.0

If I have a Vector3.Normalize() method that specifies a post condition where the resultant Vector3 is gonna have a length of 1, how would the compiler check for this at compile time (or before)? Does it just pass a random Vector3 variable to the method?
This isn't a feature of C# 4.0. It's a language-independent feature of CLR 4.0 that works at the IL level. It does have some ability to perform static checking, but not for every kind of condition. It actually analyzes the IL generated by the normal compiler for whatever language you're using, finds the constraints you put in the code and then looks at the code to figure out if it is going to meet the contract. The static checking (at least in demos I've seen) is an optional feature.
I'm pretty sure the code contracts stuff in C# 4.0 will happen at runtime, not compile time, and that you would need to actually specify the condition in the call. Supposing your Vector3 class has a Length property, you would end up with something like this:
Expects(vector3.Length == 1);
Which would actually hit some IL rewriting during a sort of post-compilation step which would end up essentially wrapping the body of the method in a try..finally where the post condition test is in the finally block.

Categories

Resources