Contracts in C# 4.0 - c#

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.

Related

Source code for the "nameof" operator of 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.

Wish: Hiding a Deprecated Method with Another Overload Using Default Parameters

Please bear with me, this is not (quite!) a duplicate of any of these SO answers:
Conflicting overloaded methods with optional parameters
Overload Resolution and Optional Parameters in C# 4
Call overload method with default parameters
When trying to "influence" what overload the compiler will choose given conflicts arising from optional parameters, answers in the above posts reference the C# Programming Guide, which indicates the overload resolution (OR) heuristics at play here:
If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call.
Fair enough. My question is, why doesn't (or why can't) the Obsolete attribute (or some other markup) influence the OR decision on judging two candidates to be equally good? For example, consider the following overloads:
[Obsolete(“This method is deprecated.”)]
[EditorBrowsable(EditorBrowsableState.Never)]]
bool foo() { return true; }
bool foo(bool optional = false) { return optional; }
It seems OR should not judge these overloads to be equally good--the non-deprecated overload with an optional parameter should win. If this were the case in this over-simplified example, code previously compiled for foo() would be backwards compatible and happily continue to return true. Future code compiled for this library could also call foo(), but that resolved overload would return false.
Is this a valuable/possible feature we are missing from the language? Or is there any other way to make this wish of mine work? Thanks for any insights,
-Mike
Overload resolution is a very tricky thing to get right, and language designers think long and hard about exactly what the rules should be. The more different considerations and special cases you add, the likely language users are to run into obscure gotchas where it doesn't quite work the way they'd expect. I don't believe adding this new condition to overload resolution would be a valuable addition to the language.
If OR did prefer the method without the ObsoluteAttribute, then the only way to invoke the obsolete method without reflection would be something like this:
((Action)obj.foo)();
And if this were a generic method, there would be no way to call it with an anonymous type parameter. This would definitely be surprising behavior (at least to me).
The ObsoleteAttribute (declared with IsError = false) is a way for you to provide a hint for your consumers to update their code without completely removing the previous capabilities. Typically you want to do this if you plan to remove the feature in a future version. If you want to prohibit them from calling this method entirely, you can either:
Set IsError = true with [Obsolete("This method is deprecated.", true)] so that if the code is re-compiled, it generates an error rather than a warning. It could still be called via reflection.
Remove the deprecated function entirely. It cannot be called via reflection.
It's an interesting question. Still, I prefer it the way it is for the following reasons:
Simplicity
OR depends on method signature compiled to module and it is intuitive at that. Depending on any attributes would change the dependency scope to a wider "thing" and start snowballing - should you consider maybe another attribute? Or attributes on arguments, etc..
Change management
Method signatures & OR are different concern than the deprecation marker attribute. The latter is metadata and if it started to affect OR from one point on, then it would possibly break many existing applications. Especially libraries where deprecation cycle is longer for a reason.
I would be very annoyed if a functionally tested code started to behave different after a soft decision that a certain part of code will be phased out in "undetermined future".
All in all having code like this ...
[Obsolete(“This method is deprecated.”)]
bool foo() { return true; }
bool foo(bool optional = false) { return optional; }
stinks. The compiler will apply an algorithm to select the right method when you call foo() but any developer looking at the code will need to know (and to apply) that algorithm to understand what the code does so maintainability of the code will decrease a lot.
Simply remove the optional in this case as it hurts more than anything else.

Resharper search pattern to detect methods that return a value that is not used

I would like a resharper pattern to detect unhandled IDisposables if possible. If I have a method
IDisposable Subscribe(...){....}
and call it without assigning and using that IDisposable I would like to be told about it. I have tried the following pattern
;$expr$;
where expr is of type IDisposable. The following happens.
the first is detected correctly but the second is an error because simple assignment to an existing variable is also and expression in C# whereas assignment using var is not. Is it possible to detect that the return value is assigned via structural search?
I notice that resharper has the following code quality options
but I'm guessing they are built with something more sophisticated than the structural search parser.
Unfortunately, this can't be done with structural search and replace. For one thing, there is no construct to match against the absence of something, so there's no way to match against a method invocation that does NOT have an assignment of its return value.
As you note, there are inspections that track pure functions that don't use the return value, and they're not implemented with SSR. You can make them apply to your methods by applying the [Pure] attribute to them. However, this is implying that the method actually is pure, i.e. has no side effects, so may be the wrong semantic in this instance.

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)

DebuggerDisplayAttribute - How does it choose the language when evaluating expressions?

http://msdn.microsoft.com/en-us/library/x810d419.aspx
From what we can see on MSDN, it says to be careful about which expressions we put as they change from language to language. My question is: what are the supported languages for writing those expressions? If various languages can do it, how does it detect which language is being used?
I've made my class in CLI, and coded the expression in c#, being that it works. I've tried in c++/CLI, but that way it doesn't.
Here is my code:
[DebuggerDisplay("z = {ToString()} Norm = {System.Math.Round(Norm,2)} Angle = {System.Math.Round(Angle, 2)}")]
Now, trying it the c++/CLI way:
[DebuggerDisplay("z = {ToString()} Norm = {System::Math::Round(Norm,2)} Angle = {System::Math::Round(Angle, 2)}")]
My assumption is that it will always read the expression as c# code. Is this true?
I found this link
There is a down-side to this power
though - because evaluation of the
DebuggerDisplayAttribute format string
is compiler-specific, the first
example will work fine most other
debuggers such as VB, but the second
one will not evaluate due to its use
of the C#-specific ternary operator.
Depending on the debugger this will
cause it to display either the default
value of the class name, or an error
indicating which part of the syntax
could not be evaluated; this may be
important if you work in a
multi-language environment, or if you
ship your classes as a library to
customers.
My interpretation is that it will always interpret it in a format that happens to look a lot like C#, yes. So . for members-access, etc (the same as data-binding uses . for member-access, regardless of the caller's language). It is also a lot like the string.Format pattern, if you see the relationship ("{0} - {1}" etc).
Of course, if the expression gets too complex you could consider a debugger type proxy.

Categories

Resources