I have been asked to help with a C# project where the source code is no longer available. Fortunately a non-obfuscated debug build of the project is available, so I ran it through Reflector and the reconstructed source code looks largely fine.
There is one oddity that I have a question about. Some objects that pretty clearly should be a string are coming out like this:
string str7 = new string();
str7.Value = strArray3[k];
Now, string does not have a parameterless constructor nor does it have a Value property. I think I can just remove the instantiation and remove the .Value property and things will probably work as expected, but I would like to understand if there might be something more going on than a Reflector bug.
One other interesting piece is that almost all of the variables were reconstructed with original-sounding names, but this one (and a few others) seem to have been assigned random names.
Any insight is very welcome.
Can you post both the IL and decompiled C# for the same method where this happens?
There isn't by chance a "class string { ... }" in that assembly, is there?
Related
Often I have the pieces of code that look like this:
private void OnChangeLanguageCommandExecuted(object obj)
{
pLngService.ChangeLanguage(newLcid);
}
In this case the ChangeLanguage(...) method returns a value, although that value (true for success, false for non-success) is not used. The problem is, I had no clue when looking at the code that this method was returning a value.
I did not write the method, nor have I control over it.
Therefore i'd like to globally enforce a policy where:
Each non-void returning method must be assigned a variable, e.g.
var unused = pLngService.ChangeLanguage(newLcid);
Or the discard operator should be used, to make it more explicit:
_ = pLngService.ChangeLanguage(newLcid);
I'm of course open to other suggestions, the main goal here is to make it more verbose that both a method is returning a value and that i'm choosing to discard it.
I was hoping there'd be a rule for visual studio or Resharper where i could enfore this policy by generating compiler warnings. I won't like to make this a compiler error, that seems to rigorous. I did some quick looking around but i did not find anything oob but i feel like im overlooking something.
I'm using projects in vs2017 (net4) and vs2019 (net8/netcore3.0) so something that would work in either of those setups would be great.
EDIT:
I found out, literally whilst writing a roslyn code analyzer, that apperently you can configure this with https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0058
The code fixes were exactly what I was looking for:
// Original code:
System.Convert.ToInt32("35");
// After code fix for IDE0058:
// csharp_style_unused_value_expression_statement_preference = discard_variable
_ = System.Convert.ToInt32("35");
// csharp_style_unused_value_expression_statement_preference = unused_local_variable
var unused = Convert.ToInt32("35");
There is the following rule:
csharp_style_unused_value_expression_statement_preference
With options:
Option values discard_variable - Prefer to assign an unused expression to a discard
unused_local_variable - Prefer to assign an unused expression to a local variable that is never used
For future readers, please refer to the code rule IDE0058:
https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0058
Also see: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options?view=vs-2019 on how to configure editor rules.
Which should provide what you need. If thats not available, or the rule is buggy in your particular version of VS you can also take a look at this quick roslyn analyzer i made on a saturday morning:
https://github.com/sommmen/DiscardReturnValueAnalyzer/tree/master
She works but there are still some things i'm not happy with, like the actual analysis messages. But since IDE0059 should already cover this use case I'm not putting more effort into this. If you need this for some reason, feel free to create an issue and I might take a look.
Also the repo is not published or something so you'd have to clone and build it yourself.
P.s. Roslyn analyzers are pretty dope once you get the hang of them.
So I'm sort of new to C# and I can't for the life of me figure out how to do this. I've read on how to do it using CodeDom http://msdn.microsoft.com/en-us/library/saf5ce06.aspx, but I just can't get anything to work. For example:
string toExecute = "Console.WriteLine('Hello world')";
//How would I make it so that toExecute is executable. i.e: Execute(toExecute);
output:
Hello world!
I've tried this and I keep getting an error(I don't even understand it!):
string toExecute = "Console.WriteLine('Hello World')";
Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(toExecute);
theMethod.Invoke(this, null);
So if someone could give me an example on how to do this one thing and explain it, then I would probably be able to work from there(If it's even possible).
Thanks in advance
I don't have my visual studio on this computer so haven't run it but I think this should work:
object[] parametersArray = new object[] { "Hello" };
MethodInfo writeLine = typeof(Console).GetMethod("WriteLine", new Type[] {typeof(string)});
writeLine.Invoke(null, parametersArray)
Maybe post what you're trying to accomplish, doing this sort of stuff is a pain in the butt especially if you're newer to .net
ref: http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx
CodeDOM is among the easiest ways of doing so. But anyway, it's quite a difficult task, since C# isn't designed to do so. It's one of the fundamental bases of static, compiled languages, all code must be known beforehand, at compile time, since it isn't interpreted on the fly as you would do with a plain string, even if it contains valid code. Really, what matters and gets executed is the bytecode inside the exe/dll.
It's also often not a good idea to try those things, as you completely lose the safety the compiler gives you, and makes your code much harder to debug when problems arise in the dynamically generated code. It's quite an advanced feature, not good for learning if you're new. Things like this are common in other dynamic languages but for C# is quite complex.
BTW, are you trying to accomplish something in particular? Or just asking if it's possible? Probably there are much easier ways of doing the same without resorting to runtime code generation.
I am doing work for a client who has lost the source code for one of their VB.Net WinForms applications. The assembly they have is not obfuscated at all. I am trying to recover as much of the source as I can as C# source and have tried several tools for decompiling assemblies, including Reflector, ILSpy and JustDecompile (all the latest versions), but they all produce code with a huge number of errors in them. Because of the large number of errors in the generated code, I am going to ask about the specific errors (in different questions), hopefully to get more directed answers and in this way try shed some light on why all the tools are having difficulty decompiling this assembly.
This question pertains to the fact that the code generated by all these tools always have a large number of invalid member variables (fields) such as the following:
private short $STATIC$Report_Print$20211C1280B1$nHeight;
private ArrayList $STATIC$Report_Print$20211C1280B1$oColumnLefts;
private StaticLocalInitFlag $STATIC$Report_Print$20211C1280B1$oColumnLefts$Init;
Can someone explain why the generated code has these invalid member variables and how I can resolve these?
Those are identifiers generated by the VB.NET compiler to implement the Static keyword. For example:
Class Example
Public Sub test()
Static lookhere As Integer = 42
End Sub
End Class
generates this IL:
.field private specialname int32 $STATIC$test$2001$lookhere
.field private specialname class [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag $STATIC$test$2001$lookhere$Init
By using reserved letters in the field name, the compiler can be sure there will never be an accidental collision with another field. There's no direct equivalent to Static in the C# language. You can leave them as private fields in the class but you have to watch out for initialization. The purpose of the $Init flag and rather a lot of IL that ensures the variable is correctly initialized. You'll need to rename them by hand.
In short, what's valid in IL isn't necessarily the same as what's valid in the source language. It's fairly common to give compiler-generated (aka synthetic in some circles) members name which are invalid in the language, as it avoids any possible clashes. These are sometimes called unspeakable names as they can't be "spoken" in the source language. For example, the C# compiler usually includes <> in such names.
As for resolving the issue - some decompilers will work out where such names have come from automatically, but you can usually simply change the name everywhere. You won't end up with the original source code, but if you look at what you do end up with, you may be able to then work out more easily what the original source did look like.
Note that the compiler may generate more than just invalid names: in C#, for example, iterators blocks generate IL which in some cases can't be expressed directly in "normal" C# itself. This may not be a problem for you, but it's worth being aware of.
Those aren't variables, they are fields (they have access modifiers).
They will be compiler generated fields which will be generated in a number of different circumstances. The names are purposely invalid to avoid conflicts with "normal" fields.
If you can provide a little more context someone clever can probably figure out what the source originally looked like for the compiler to emit those fields.
Quite often I see source code where language's keyword are replaced with full type names:
System.String, System.Int32, System.GUID etc.
Moreover, people who do this write complete type names everywhere, making source full of such declarations:
System.Collections.Generic.List<System.Reflection.PropertyInfo> list = System.Collections.Generic.List<System.Reflection.PropertyInfo>(newSystem.Reflection.PropertyInfo[] { ... });
When I ask them why do they do this, i get wide range of answers: "It helps me avoid type names collisions", "It looks more professional", "my VS plugin does it for me automatically" etc.
I understand, sometimes writing full type names helps you avoid writing unnecessary using if you use the type one time throughout the source code file. And sometimes you need to declare a type explicitly, a great example is Threading Timer and WinForms Timer.
But if you source full of DB calls and you still write System.Data.SqlClient.SqlCommand instead of 'SqlCommand' it looks quite a bit strange for me.
What do you think? Am i right or i just don't understand something?
Thank you!
P.S. And another phenomena is writing if (0 != variable) instead of if (variable != 0).
The if (0 == variable) thing is a C++ convention used to protect against accidentally writing if (variable = 0), which is valid in C++ however doesn't do what's intended. Its completely unnecessary in C# as the wrong version doesn't compile, so you should use the other version instead as it reads better.
Personally I like to write as little as possible, so unless there is a namespace clash I never fully qualify things.
As for string vs String, I always use the alias (string / int) rather than the full class name, however its purely a convention - there is no runtime difference.
I'd argue strongly against "it looks more professional", as frankly it looks the opposite to me.
That said, if I was to use a single member of a namespace in the entire source file, I might use the full name there rather than have a using.
Favouring 0 != x over x != 0 etc. does have some advantages depending on overrides of equals and a few other things. This is more commonly so in some other languages, so can be a hangover from that. It's particularly common to see people favour putting the null first, as that way it's less likely to be turned into passing null to an equality override (again, more commonly a real issue in other languages). It can also avoid accidental assignment due to a typo, though yet again this is rarely an issue in C# (unless the type you are using is bool).
It is a bit subjective but unless your coding standard says otherwise I think removing the namespace is always better as it is less vebose and makes for easier reading. If there is a namespace collision, use a shorter alias that means something.
As to your last point, if you compare name.Equals("Paul") vs "Paul".Equals(name). They both do the same thing unless name is null. In this case, the first fails with a null exception, whilst the 2nd (correctly?) returns false.
For primitive data types: Duplicate questions here - C#, int or Int32? Should I care?
For non-primitive data types: The answers given are valid, especially "It helps to avoid type names collisions"
For if (0 != variable): variable is the subject to compare in the expression, it should go first. So, I would prefer if (variable != 0).
I don't find any of these reasons convincing. Add using statements is better.
Two minor exceptions:
In generated code, you may see redundant namespace prefixes, but that is OK as this code is not indented to edited.
Sometimes it is helpful to write Int32 explicitly when depend on the type being exactly 32 bits.
Make code as readable as possible! See also: http://en.wikipedia.org/wiki/KISS_principle
"It looks professional" is a very bad argument.
BTW, if your code is full of SQL statements, then you may want to refactor that anyway.
About string vs String. I try to use string, when it is that, i.e. a string of characters as in any programming language. But when it is an object (or I am referring to the String class), I try to use String.
Imagine someone coding the following:
string s = "SomeString";
s.ToUpper();
We all know that in the example above, the call to the “ToUpper()” method is meaningless because the returned string is not handled at all. But yet, many people make that mistake and spend time trying to troubleshoot what the problem is by asking themselves “Why aren’t the characters on my ‘s’ variable capitalized”????
So wouldn’t it be great if there was an attribute that could be applied to the “ToUpper()” method that would yield a compiler error if the return object is not handled? Something like the following:
[MustHandleReturnValueAttribute]
public string ToUpper()
{
…
}
If order for this code to compile correctly the user would have to handle the return value like this:
string s = "SomeString";
string uppers = s.ToUpper();
I think this would make it crystal clear that you must handle the return value otherwise there is no point on calling that function.
In the case of the string example this may not be a big deal but I can think of other more valid reasons why this would come in handy.
What do you guys think?
Thanks.
Does one call a method for its side-effects, for its return value, or for both? "Pure" functions (which have no effects and only serve to compute a return value) would be good to annotate as such, both to eliminate the type of error you describe, as well as to enable some potential optimizations/analyses. Maybe in another 5 years we'll see this happen.
(Note that the F# compiler will warn any time you implicitly ignore a return value. The 'ignore' function can be used when you want to explicitly ignore it.)
If you have Resharper it will highlight things like this for you. Cant recommend resharper highly enough, it has lots of useful IDE additions especially around refactoring.
http://www.jetbrains.com/resharper/
I am not sure that I like this. I have called many a method that returns a value that I choose not to capture. Adding some type of default (the compiler generates a warning when a return value is not handled) just seems wrong to me.
I do agree that something along the suggested lines might help out new programmers but adding an attribute at this point in the game will only affect a very small number of methods relative the the large existing body. That same junior programmer will never get their head around the issue when most of their unhandled return values are not flagged by the compiler.
Might have been nice way back when but the horses are out of the barn.
I'd actually prefer a way to flag a struct or class as [Immutable], and have this handled automatically (with a warning) for methods called without using their return values on immutable objects. This could also protect the object by the compiler from changes after creation.
If the object is truly an immutable object, there really would be no way to handle it. It also could potentially be used by compilers to catch other common mistakes.
Tagging the method itself seems less useful to me, though. I agree with most of the other comments regarding that. If the object is mutable, calling a method could have other side-effects, so the above code could be perfectly valid.
I'm having flashbacks to putting (void) casts on all printf() calls because I couldn't get Lint to shut up about the return value being ignored.
That said, it seems like this functionality should be in some code checker tool rather than the compiler itself.
At least a compiler-warning would be helpful. Perhaps they add something similar for C# 4.0 (Design-By-Contract).
This doesn't warrant for a warning or pragma. There are too many places where it is intended to discard the result, and I'd be quite annoyed getting a warning/error from the compiler just because the method was decorated with some dodge attribute.
This kind of 'warning' should be annotated in the IDE's Editor, like a small icon on the gutter "Warning: Discarding return value" or similar.