VS cannot show information on variable - c#

I have some arbitrary code. e.g. the following:
class MyClass
{
private MyClass() { }
public static readonly MyClass Instance = new MyClass();
public Hashtable DoSomething() {return new Hashtable {{"key", "value"}};}
}
var test = MyClass.Instance.DoSomething();
Now when debugging and hovering test intellisense doesn´t show anything at all. Also adding a watch to the variable does not work. Instead the message
The name 'test' does not exist in the current context
appears. I already rebuilt the solution, closed VS and re-opened it. However when NOT debugging I get type-information on that variable within intellisense.
NB: Unfortunetaly the code above works within my test-solution, however the actual code which is far more complex does not. I already tried to simplify this as much as I can, supposing some downvotes as the error is hardly to reproduce. However maybe anyone has had a similar problem on VS.
EDIT: Optimization of code is disabled within projects settings (Properties-->Build-->optimize code)

The compiler most likely optimizes the variable away because it is never used locally.
Use the variable in any way to circumvent this:
var test = MyClass.Instance.DoSomething();
Debug.WriteLine(test); // <=== Set breakpoint here
I'm not 100% sure, but I think optimizations also affect this. So to be sure, turn them off if you have these problems.

Related

Running multiple lines on the immediate window in Visual Studio with C#

Is there a way to run multiple commands in a single entry in the immediate window of Visual Studio? I am running Visual Studio 2013.
I have a problem that is much easier to debug when I can create an input object within the immediate window and step through, but every time I make a change to the code I have to recreate the object like this:
var inputObject = new InputObject();
inputObject.Property1 = "value";
inputObject.Property2 = "value";
inputObject.Property3 = "value";
//etc.
It's a pain to have to rebuild this object by running each line individually to help debug this problem I have. Is there a way to run them all in one command? Something like this (though obviously this does not work):
var inputObject = new InputObject(); inputObject.Property1 = "value"; inputObject.Property2 = "value"; inputObject.Property3 = "value";
I do see that it is possible in Visual Basic from this link: Using colons to put two statements on the same line in Visual Basic
Any suggestions for other approaches to achieve the end goal are also welcome.
In short, no. I don't believe the Immediate Window supports multiple statements at this time.
edit -- #Christopher_G_Lewis is actually correct, you can declare and instantiate new variables, but I found that the statement must be terminated with a semi-colon, unlike many other expressions that may be evaluated without one.
What you are doing comes across as a difficult method of debugging. If you have an issue that is difficult to debug without conventional methods (e.g. stepping through code, breakpoints, tracing) you should consider a Debugging Aid.
Debugging aids can vary, but why not just actually compile in that small snippet of code temporarily to help you troubleshoot the problem? The Immediate Window in Visual Studio isn't really intended to create control flow or new objects on demand, but is more designed for executing simple statements and expressions for quick analysis.
Your example is a bit vague to recommend a specific approach though, and I'm unsure what you are actually trying to accomplish. A simple struct in your code would still allow you to use it via the Immediate Window, and if you are concerned about accidentally leaving it in code you can use a #DEBUG constant to ensure it doesn't get compiled into your release configurations.
#if DEBUG
struct DebuggingAid
{
public string A;
public string B;
public string C;
}
#endif
#if DEBUG
public void f()
{
var aid = new DebuggingAid { A = "TestValue1", B = "TestValue2" };
// var real data
MethodBeingDebuggedWithStubDebuggingAidData(aid.A, A.B);
}
#endif
I would definitely consider different debugging methods that are available to you though.
Breakpoints are more powerful than you might realize. You can set conditional statements and also print out information when a breakpoint is hit and even call functions.
Function Breakpoints allow you break on a method of a particular name in the event you can't track down when it might be called, or where it is called from. You can also set conditions and actions.
Tracing with System.Diagnostics.Debug and System.Diagnostics.Trace to assist in debugger output in the IDE, you can also write traces to files.
Debugging aids, as already shown, and remove them from your code when you're done, or leave them in but compiled out #if DEBUG.
Unit testing - There is no wrong time to add a unit test to your code base. You will need to refactor your code slightly to facilitate testability, such as passing in dependencies, which it may appear that is what you are trying to do? (stubbing in test values to something?).
Immediate Window, by just manipulating the real data you are trying to (stub?) rather than creating debugging aids or test objects
If you could provide a little more detail about what you are trying to accomplish it will be a bit easier to provide some guidance, but hopefully this has helped you.
Actually its pretty simple to initiate an object in the immediate window:
inputObject = new InputObject()
{TestMVC.Areas.UI.Controllers.ServersController.InputObject}
Property1: null
Property2: null
Property3: null
inputObject = new InputObject() {Property1 = "1", Property2 ="2", Property3 = "3"}
{TestMVC.Areas.UI.Controllers.ServersController.InputObject}
Property1: "1"
Property2: "2"
Property3: "3"
But this is still a single command. Multiple commands are not supported.
If these were just props of the same class I'd go like ChristopherGLewis's answer
You can run multiple disparate assignments (i.e. setting props in different classes, or assigning unrelated variables) by stuffing them into an array all on the same line; don't forget that assignments in c# return values...
new object[]{ some.Prop1 = "hello", other.Prop2 = "goodbye", third.Prop3 = GetSomeValue(), myArray[0] = 2, _timeNow = DateTime.Now }
You get an object array back (and immed dumps it to the window), but as part of creating the array, immed ran the statements..
some.Prop1 = "hello";
other.Prop3 = "goodbye";
third.Prop3 = GetSomeValue();
myArray[0] = 2;
_timeNow = DateTime.Now;
..captured their return values, and put them in the array. As a side effect of each evaluation, the assignments you wanted made, were done - you probably don't care about the return values
I don't know of a way to do this with voids (i.e. I don't know how to make the immed window run 2 void methods on a single line); everything I've tried responds with calls into native method Microsoft.Win32.Win32Native.GetStdHandle(int). Evaluation of native methods in this context is not supported
//doesn't work
new [] {(Action)(() => { Console.WriteLine("a"); Console.WriteLine("b"); })}.ToList().ForEach(x => x())
Actually it does work, probably because I am writing this answer 5 years after this question was written.
You see below I have declared a local var in the Immediate window then pressed Enter and used it in a later line in the Immediate window. I am using Visual Studio v.16.11.6

How to avoid property recursion

This hit me recently on a project I was working on. Most people are familiar with property recursion:
public int Test
{
get { return this.test; }
set { this.Test = value; }
}
private int test;
You accidentally put an upper-case T in this setter, and you've opened yourself up to a StackoverflowException. What's worse is if you've not defined it, often visual studio will auto-correct the casing for you to the invalid state.
I did something similar however in a constructor recently:
public TestClass(int test)
{
this.Test = Test;
}
Unfortunately here you don't get a StackOverflowException, now you've got a programming error. In my case this value was passed to a WebService that instead used a default value (which wasn't 0) which caused me to miss the fact I had incorrectly assigned it. Integration tests all passed because this service didn't say
"Hey you forgot this really important field!"
What steps can I take to avoid this sort of behaviour? I've always been advised against defining variables like the following, and I don't like them personally, but I can't think of any other options:
private int _test;
private int mTest;
EDIT
Reasons that the underscore or m prefix are undesirable normally that I can think of are:
Readability
Slightly more difficult to scroll through members if you're inheriting from 3rd party classes as you get a mix of styles.
Best way is to use "Auto implemented properties" here.
public int Test { get; set; }
If not possible to use "Auto implemented properties" for some reason use _ prefix(I don't prefer though).
If you also don't prefer to use some prefixes, then you have other option. You don't have to write the property code by hand. Let the IDE do it for you; that way you can avoid careless mistakes. (I don't know how I missed this in original answer)
Just type
private int test;
Select the field, Right click Refactor->Encapsulate Field. IDE will generate property snippet for you as below.
public int Test
{
get { return test; }
set { test = value; }
}
You don't need to bother clicking the context menu. If you prefer keyboard, shortcut is Ctrl + R + E.
Or get a Resharper, It will point your silly mistake immediately.
Integration tests all passed
Then they weren't exhaustive enough tests. If there's an error that wasn't discovered by the tests, then you've got another test to write.
That's really the only automated solution here. The compiler isn't going to complain, because the code is structurally and syntactically correct. It's just not logically correct at runtime.
You can define naming standards, even use tools like StyleCop to attempt to enforce those standards. That would probably allow you to cover a lot, though it's not an ironclad solution and errors can still get through. Personally I agree with you that decorating variable names is unsightly in the code. Perhaps in some cases it's a valid tradeoff?
Ultimately, automated tests are your defense against these kinds of errors. At its simplest, if an error gets through your tests and into production then the response should be:
Write a test to reproduce the error.
Fix the error.
Use the test to validate the fix.
Granted, that only covers that one case, not every property definition in your code. But if this is happening a lot then you may have a personnel problem and not a technical problem. Somebody on the team is, well, sloppy. The solution to that problem may not be a technical one.
Use code snippets.
For every property backed by a private field, use a custom code snippet you have created, instead of writing it up from scratch or letting IntelliSense do the job (poorly).
After all, this problem is about conventions and discipline, rather than language design. The case sensitive nature of C# and the subperfect code completion in Visual Studio are the reason we make these mistakes, not our lack of knowledge and design.
You best bet here is to eliminate the chance of accidents and having a predefined way of writing these repetitive things correctly is the best way to go. It also is much more automated compared to remembering conventions and enforcing them by hand.
There is a default code snippet in Visual Studio for this. Type propfull and hit Tab, then specify the instance variable name and the property name and you're good to go.
In some cases you cannot get around setters and getters. But maybe you don't need the setters and getters if you follow the Tell, Don't Ask principle? It basically says to prefer having the object that has the data do the work, not some other object query a lot from the data object, make decisions, and then write data back to the data object. See http://martinfowler.com/bliki/TellDontAsk.html
Could you not just write a test to cover this?
int constructorValue = 4;
TestClass test = new TestClass(constructorValue);
Assert.Equals(test.Test, constructorValue);
You may not want to write tests immediately to cover yourself from future wobbles, but you've found a bug, why not protect yourself from it again?
For the record, if I need a private field to store the value for a pulic getter/setter, I always underscore it. There's just something an underscore that screams privacy!
public string Test
{
get { return _test; }
set { _test = value; }
}
private string _test;

How to prevent optimization on a class field in C#

I have built an abstract class that is used to handle command line options for our products.
One need only to create a class inheriting from AbstractOptions, fill it with decorated fields and call the inherited Parse(args) method to have it automatically filled through reflection with values from the command line. Values that were not found on the command line retain their current (default) values.
Then, the application needs only to check the option fields to get their value. The AbstractOptions class provides more features, like help output, etc, but it is beside the point.
Short example:
public class SignalOptions: AbstractOptions
{
[Option("-i, --iterations", "Number of iterations (0 = infinite).")]
volatile public int NumberOfIterations;
[Option("-s, --silent", "Silent mode, only display final results.")]
volatile public bool Silent;
[Option("-w, --zwindow", "Window size for z-score analysis.")]
volatile public int ZWindow = 7;
[Option("-a, --zalert", "z-score value to consider as peak.")]
public double ZAlert = 2.1;
}
static void Main(string[] args)
{
var opts = new SignalOptions();
opts.Parse(args)
// If optimizations are turned off, SILENT will be written or not
// followind presence or absence of the --silent switch on the command line.
// If optimizations are turned on, SILENT will never be written.
// The reflection part is working fine. I suspect the problem is that
// the compiler of the jitter having never found this set anywhere simply inlines
// the value 'false' inthe if, because when I step on it, it shows me the value as
// true or false, but has the same behavior no matter what value opts.Silence has.
if( opts.Silent )
Console.Writeline("SILENT");
}
Now, the problem I have is that since the compiler does not find any code actually changing the values of the SignalOptions class, it simply inlines the values where they are used in the code. I have circumvent the issue by requiring that all 'option' fields in the class be volatile, so no optimization is applied, and it works fine, but unfortunately the volatile keyword is not valid on a double.
I have spent much time on the net trying to find a workaround, without success. Is there anyway to either prevent optimizations on the fields or otherwise fool the compiler/jitter into thinking they are used at runtime?
I also would like to put as less as possible the onus on the calling application.
Thanks
I have a local copy here with Parse written as the rather opaque:
public void Parse(string[] args)
{ // deliberately opaque, not that it would make any difference
string fieldName = (new string('S', 1) + "ilentX").Substring(0, 6);
GetType().GetField(fieldName).SetValue(this, true);
}
It works fine. I do not believe the problem is what you think it is.
Here is my guess:
Parse is running in a separate thread, but as your synchronization is somehow flawed, this makes the rest of code run without having the values set already.
This would also explain why you are seeing the correct values in the debugger.
Update (opinionated):
Having Parse run in a separate thread is very weird, and should be considered a design flaw. Sounds like someone was thinking 'Reflection is slow, let's put it in a separate thread'.

How to prevent C# compiler/CLR from optimizing away unused variables in DEBUG builds?

While debugging I tried to save intermediate results of a calculation to a variable so that when a breakpoint condition is met I could check that value. However C# compiler (or CLR) optimized away that variable as unused. I solved the problem by making the variable a public field of the class, however I'd like to know if there is a straightforward solution to this problem.
"Optimize code" checkbox is unchecked. The build configuration is Debug.
Edit: Found that it only affects some unused variables in iterators that would normally end up as fields in the automatically generated iterator class; unused variables that are scoped within blocks not containing yield statements are retained.
The lazy option would be.... use the value, ideally in a way that doesn't allow it to be held on the stack. For example:
var tmp = SomeMethod();
// your other code
Debug.WriteLine(tmp);
the use of the value as an argument means it must be retained, but that line is automatically not compiled into release builds.
However! I must emphasize that locals are pretty-much always retained in an unoptimized/debug build, so I'm finding the scenario from the question hard to envisage.
If you are using Visual Studio, why not just add a breakpoint on the line following the line on which the calculation is being made, and then you can simply hover over the calculation to see the result in the intellisense/tooltip popup? I also think that you can add the calculation to the "watch" screen and view the result that way as well.
This is usually how I view the results of things I am debugging. Alternatively, you could just use the temp variable you created in some simple way to avoid getting the warning.
For example:
Console.Write(tempVariable);
Handy utility:
using static _globals;
static class _globals
{
[MethodImpl(MethodImplOptions.NoInlining), DebuggerHidden]
public static void Nop<T>(out T x) => x = default(T);
};
class Program
{
static void Main()
{
int i; // unreferenced variable
/// ...
Nop(out i);
/// ...
}
};
You need uncheck options "Optimize code" in project options for Debug build.
In my case "Optimize code" option was unchecked, still I was facing this issue. I checked it, build project then unchecked it and buid project again. This fixed issue for me.

C# Static Variable forgets value

It sounds a little weird, but I've got some code (which actually is a plugin for MS Blend) that runs perfect in unit testing, but is not working within Blend.
The code is the following.
private static volatile QWGUIRepository s_instance;
public static void Initialize(IUnityContainer container, string themeuri)
{
lock (s_lock)
{
s_instance = new QWGUIRepository();
QWRepository.Initialize(container);
}
}
In the debugger (after attaching it to Blend), I can see that s_instance gets initialized with a value (is not null afterwards), however as soon as I get out of the method "s_instance" will forget it's value and will be null.
Any ideas?
Thanks,
Andreas
Two guesses:
1) You're reading in a different AppDomain than you're writing in. Static variables are scoped by AppDomain. If you look at AppDomain.CurrentDomain in the debugger during Initialize and then when you're trying to read it, does it look like they're the same domain?
2) You've actually declared s_instance to be a local variable in Initialize, and aren't touching the static variable. Hopefully that's not the case, but you never know...
I don't know anything about Blend, so this is a wild guess. Does Blend start the plugins in separate AppDomains? You can check that in the debug location toolbar in Visual Studio. That could explain it...
thanks for suggestions. Unfortunately (as usual) it was personal stupidity...
The answer is - make sure you only use strong-named assemblies.
Andreas

Categories

Resources