.NET Reflector and getters/setters issue - c#

I'm using an up-to-date .NET Reflector to disassemble an internal legacy app whose source code is almost impossible to recover. I need to find the cause of a nasty bug, and then possibly patch it. Reflector did a good job as usual in the re-creation of the project's structure, but soon I discovered that some property calls were left "expanded" to its get_() and set_() method signatures, rendering the source code impossible to compile.
At first, I thought that every get/set call had the problem. But at a closer look, several of them are OK, while others (especially OleDbCommand and Forms.Control properties) will be generated as get_() and set_().
A quick Visual Studio "Search/Replace" with regex solved these cases, but it's awkward. Is there a way to make Reflector behave correctly?
EDIT 1 - Sample problematic code below:
/* Generated by .NET Reflector 6.1.0.11 */
/* The variable selectCommand is a OleDbCommand. */
string parameterName = "#P" + Convert.ToString(num);
selectCommand.set_CommandText(selectCommand.get_CommandText() + " WHERE SIGLA = " + parameterName);
/*
Expected something like this (as ugly as it may seem):
selectCommand.CommandText = selectCommand.CommandText + " WHERE SIGLA = " + parameterName;
*/
EDIT 2 - The assembly was built in Release mode.

Where are you viewing the source code in Reflector? In the current version (6.1.0.11 at the time of this writing), disassembling a type then clicking on "Expand Methods" at the bottom yields a full class definition with code, including the correct property syntax (get { ... } and set { ... })

This problem appears with disassembling to Managed C++, right? Might want to disassemble to C# code (there is dropdown in the toolstrip) and you will get the usual properties.

So even if this question is quite old an a correct answer will never be achieved, you can now maybe give the the new tool on the block ILSpy a chance.
Maybe it will produce some better source code out of the box.

Related

Is it possible to compile only changes in Roslyn?

I made a C# compilation program with Roslyn. However, it takes about 1 second to compile the entire project.
I'm trying to optimize the time and here's my try:
// I'm currently recycling the compilation object.
if (compiler == null)
compiler = CreateCompiler();
/* ... */
for (var tree in syntaxTrees) {
SyntaxTree oldTree;
if (PreviouslyAddedAndHasChanges(tree)) {
compiler = compiler.ReplaceSyntaxTree(oldTree, tree);
}
else if (NewlyAdded(tree)) {
compiler = compiler.AddSyntaxTree(tree);
}
}
compiler.Emit(...);
But it doesn't work. Output assembly won't be changed.
I also take a look EmitDifference method, but it does not work with .dll output.
Here's my question:
Is it safe to re-use CSharpCompilation object just like my first line of the code?
Does Roslyn caching previous compilation data and should I invalidate it?
Self answer:
I fixed it now. The problem was not related with Roslyn.
The two assemblies have exactly the same name, so Assembly.Load() does not work at all.
Here's my solution to fix it.
compiler = compiler.WithAssemblyName("some_name" + (new System.Random()).Next(10000000));
And, the answers are:
Yes
I'm not sure, but it seems that they re-compile it if there is any changes.

C# possible null pointer exception [duplicate]

Here is a piece of code:
IUser user = managerUser.GetUserById(UserId);
if ( user==null )
throw new Exception(...);
Quote quote = new Quote(user.FullName, user.Email);
Everything is fine here. But if I replace "if" line with the following one:
ComponentException<MyUserManagerException>.FailIfTrue(user == null, "Can't find user with Id=" + UserId);
where function implementation is following:
public abstract class ComponentException<T> : ComponentException
where T : ComponentException, new()
{
public static void FailIfTrue(bool expression, string message)
{
if (expression)
{
T t = new T();
t.SetErrorMessage(message);
throw t;
}
}
//...
}
Then ReSharper generates me a warning: Possible 'System.NullReferenceException' pointing on 1st usage of 'user' object.
Q1. Why it generates such exception? As far as I see if user==null then exception will be generated and execution will never reach the usage point.
Q2. How to remove that warning? Please note:
1. I don't want to suppress this warning with comments (I will have a lot of similar pieces and don't want to transform my source code in 'commented garbage);
2. I don't want to changes ReSharper settings to change this problem from warning to 'suggestion' of 'hint'.
Thanks.
Any thoughts are welcome!
P.S. I am using resharper 5.1, MVSV 2008, C#
Resharper only looks at the current method for its analysis, and does not recursively analyse other methods you call.
You can however direct Resharper a bit and give it meta-information about certain methods. It knows for example about "Assert.IsNotNull(a)", and will take that information into account for the analysis. It is possible to make an external annotations file for Resharper and give it extra information about a certain library to make its analysis better. Maybe this might offer a way to solve your problem.
More information can be found here.
An example showing how it's used for the library Microsoft.Contracts can be found here.
A new answer in old post...
Here a little sample of my code regarding how to use CodeContract via ContractAnnotation with Resharper:
[ContractAnnotation("value:null=>true")]
public static bool IsNullOrEmpty(this string value)
{
return string.IsNullOrEmpty(value);
}
It is very simple...if u find the breadcrumb in the wood. You can check other cases too.
Have a nice day
Q1: Because Resharper doesn't do path analysing. It just sees a possible null reference and flags that.
Q2: You can't without doing either of what you provided already.
You do know (or expect) that this code will throw an exception if there is a null reference:
ComponentException<MyUserManagerException>.FailIfTrue([...]);
However, since there is no contract specifying this, ReSharper has to assume that this is just a normal method call which may return without throwing any exception in any case.
Make this method implement the ReSharper contract, or as a simple workaround (which only affects debug mode, therefore no performance penalty for release mode), just after the FailIfTrue call:
Debug.Assert(user != null);
That will get rid of the warning, and as an added bonus do a runtime check in debug mode to ensure that the condition assumed by you after calling FailIfTrue is indeed met.
This is caused by the Resharper engine. These "possible NullReferenceException" happen because someone (probably at Resharper) has declared/configured somewhere an annotation on the method.
Here is how it works: ReSharper NullReferenceException Analysis and Its Contracts
Unfortunately, sometimes, these useful annotation are just wrong.
When you detect an error, you should report it to JetBrains and they will update the annotations on the next release. They're used to this.
Meanwhile, you can try to fix it by yourself. Read the article for more :)
Please check if you have any user==null if check above the given code. If there is, then ReSharper thinks that the variable "can be null" so recommends you to use a check/assert before referencing it. In some cases, that's the only way ReSharper can guess whether a variable can or cannot be null.

Uses for [Obsolete(string, bool)] attribute for .NET

Note: I already checked msdn, it doesn't address my actual question, see below.
I'm trying to use the obsolete attribute on a (obviously obsolete) constructor in one of my classes. Here's the scenario:
I want to be able to force the developer to update to the new constructor without affecting already existing and deployed code. This way I can deploy my code to production just fine, but from a developers perspective, whenever they go into their code, instead of just getting a "warning" which I'm sure they'll just ignore, I want them to get a compile error because the status quo is no longer ok.
So my question is, will this affect only developers, or all calling apps, or do I have the whole thing wrong?
sample code:
public class MyClass
{
private string _userID; //new code
[Obsolete("This constructor is obsolete, please use other constructor.", true)]
public MyClass()
{
_userID = ""; //defaulting to empty string for all those using this constructor
}
public MyClass(string userID)
{
_userID = userID; //this is why they need to use this constructor
}
}
Any and all help will be appreciated, thanks in advance!
Yes, this primarily affects the compiler - any pre-built code won't be affected... unless that code explicitly checks for this attribute. For example, some serialization code (XmlSerializer, IIRC) checks for this - so it might not be entirely side-effect free... but in principal existing code won't usually be affected until they try to compile next.
Of course, if you are using this code from something that uses dynamic compilation (for example ASP.NET without pre-compile) then all bets are off.
The attribute is only an instruction to the compiler. Already existing binaries can still use the constructor.
So my question is, will this affect only developers, or all calling apps, or do I have the whole thing wrong?
This will only be used at compile time, by the compiler. It will not affect applications which have already been deployed.
As such, this will have the behavior you are trying to accomplish.
This is what [Obsolete] already does, no extra help is needed. It is not a compile time warning, it generates an error:
error CS0619: 'ConsoleApplication1.MyClass.MyClass()' is obsolete:
'This constructor is obsolete, please use other constructor.'

Is there .net magic to get parameter values by name in console application?

I've been developing .net console applications using C# and have always just dictated what order parameters must be inserted in so that args[0] is always start date and args[1] is always end date, for example.
however I would like to move over to using named parameters so that any combination of parameters can be sent in any order, such as the typical "-sd" would prefix a start date.
I know I could parse through the args[] looking for "-" and then read the name and look the next position for the accompanying value, but before doing that wanted to see if there was any kind of baked in handling for this rather standard practice.
is there something like this out there already that could do as such:
DateTime startDate = (DateTime)((ConsoleParameters)args[])["sd"]
I'm using C# and .Net 4
There is nothing built into the core framework.
A lot of people think NDesk.Options is useful for this sort of thing. Check out this example (taken directly from the provided link):
string data = null;
bool help = false;
int verbose = 0;
var p = new OptionSet () {
{ "file=", v => data = v },
{ "v|verbose", v => { ++verbose } },
{ "h|?|help", v => help = v != null },
};
List<string> extra = p.Parse (args);
Yes, the "magic" is that this is a common problem and it has been adequately solved. So I recommend using an already written library to handle parsing command line arguments.
CommandLineParser has been great for me. It is reasonably documented and flexible enough for every type of command line argument I've wanted to handle. Plus, it assists with usage documentation.
I will say that I'm not the biggest fan of making a specific class that has to be adorned with attributes to use this library, but it's a minor point considering that it solves my problem. And in reality forcing that attributed class pushes me to keep that class separate from where my app actually retrieves it's settings from and that always seems to be a better design.
You can use NDesk.Options.
There is no such a thing as named parameters. "-sd" is just a choice for a specific application. It can be "/sd" as well. Or "sd=". Or whatever you want.
Since there are no named parameters, there is nothing inside .NET Framework which let you use the "-sd" syntax.
But you can quite easily build your own method to get a set of "named parameters" for your app.
Edit: or, even better, you can use an existing library, like suggested in other answers.
Edit: reading the answer by #Sander Rijken, I see that I was wrong: there were still an implementation of "-sd" syntax in .NET 4.0 before the release. But since it was dropped before the final release, the only ways are still to create your own method or to use an existing library.

C# version of __FUNCTION__ macro

Does anyone has a good solution for a C# version of the C++ __FUNCTION__ macro? The compiler does not seem to like it.
Try using this instead.
System.Reflection.MethodBase.GetCurrentMethod().Name
C# doesn't have __LINE__ or __FUNCTION__ macros like C++ but there are equivalents
What I currently use is a function like this:
using System.Diagnostics;
public string __Function() {
StackTrace stackTrace = new StackTrace();
return stackTrace.GetFrame(1).GetMethod().Name;
}
When I need __FUNCTION__, I just call the __Function() instead. For example:
Debug.Assert(false, __Function() + ": Unhandled option");
Of course this solution uses reflection too, but it is the best option I can find. Since I only use it for Debugging (not Tracing in release builds) the performance hit is not important.
I guess what I should do is create debug functions and tag them with
[ Conditional("Debug") ]
instead, but I haven't got around to that.
Thanks to Jeff Mastry for his solution to this.
Unfortunately there is no equivalent version of that macro in C#. I don't consider the GetCurrentMethodName() solution equivalent to the C++ __FUNCTION__ macro. Namely becase the C++ version is a compile time computation of the name. For C# this is a runtime calculation and incurs a performance hit.
I'm not making any assumtions about the severity of the cost but there is one
The following should work, although it will be evaluated at runtime instead of during compilation.
System.Reflection.MethodBase.GetCurrentMethod().Name
I use this:
public static string CallerName([CallerMemberName] string callerName = "")
{
return callerName;
}
Usage example:
s_log.DebugFormat("{0}", CallerName());
The down side of using it is that every time you want to print the caller name, you need to jump to the function ==> time consuming & performance hit!
So, I use it for debugging perpose and if I need to print also in production code, I usually inline the function name into the log.Debug, e.g. :
s_log.Debug("CallerName");
HTH..
This is added in .NET 4.5.
See #roken's answer here:
Do __LINE__ __FILE__ equivalents exist in C#?

Categories