Running multiple lines on the immediate window in Visual Studio with C# - 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

Related

What are best way to resolve C# unnecessary assignment (IDE0059) warnings?

I frequently write code that assigns a value to a local variable but do not use the value. I do this because it can be useful to examine the value in the debugger (without which I'm not sure how I could examine the variable). But the C# compiler gives a warning about this. The suggested potential fixes aren't what I want and I'm wondering what best practices there may be to handle this. I tried using a discard ('_') but don't seem to be able to examine the value in the debugger. Suppressing the warning doesn't seem a great idea because there are times when I really do need to clean up the code. Suggestions welcome.
Example:
[Fact]
public void TestDuplicateValue()
{
string value = "A";
FieldValue fv1 = new FieldValue(value);
FieldValue fv2 = new FieldValue(value);
// Should not throw an exception
FieldValueCollection fvc = new FieldValueCollection(new FieldValue[] { fv1, fv2 });
}
Hmm ... It's really hard to answer questions about things that don't make sense. But you kinda do make sense. I can understand you. Since you really don't want to ignore the warning and I understand why, we have to get creative :)
There really is no way to get rid of the warning message unless you ignore it, or you actually use it.
But there's a solution to everything, even if it's not great, so I give you two options:
Option 1
Just comment the line and uncomment it, when you actually need it
Option 2
Do something like the following. The Debug.Assert statement breaks execution like a breakpoint, when the given condition is false. Since your fvc variable will never be false, that breakpoint will never be triggered. But still the variable is being used and you get rid of your warning message.
[Fact]
public void TestDuplicateValue()
{
string value = "A";
FieldValue fv1 = new FieldValue(value);
FieldValue fv2 = new FieldValue(value);
// Should not throw an exception
FieldValueCollection fvc = new FieldValueCollection(new FieldValue[] { fv1, fv2 });
System.Diagnostics.Debug.Assert(fvc != null);
}
Option 3
While I'm thinking about it, here's a bonus one. You comment that line. But when you're debugging your code, you can copy and paste your instruction into a Watch Window, and can the value of it. Use VisualStudio Menu, Debug/Windows/Watch/Watch1 - Only available while debugging
Edits
Replaced uncomment by comment and made it bold

Checking if atleasst one element in a list of a particular column has a value [duplicate]

Why can't I use lambda expressions while debugging in “Quick watch” window?
UPD: see also
Link
Link
No you cannot use lambda expressions in the watch / locals / immediate window. As Marc has pointed out this is incredibly complex. I wanted to dive a bit further into the topic though.
What most people don't consider with executing an anonymous function in the debugger is that it does not occur in a vaccuum. The very act of defining and running an anonymous function changes the underlying structure of the code base. Changing the code, in general, and in particular from the immediate window, is a very difficult task.
Consider the following code.
void Example() {
var v1 = 42;
var v2 = 56;
Func<int> func1 = () => v1;
System.Diagnostics.Debugger.Break();
var v3 = v1 + v2;
}
This particular code creates a single closure to capture the value v1. Closure capture is required whenever an anonymous function uses a variable declared outside it's scope. For all intents and purposes v1 no longer exists in this function. The last line actually looks more like the following
var v3 = closure1.v1 + v2;
If the function Example is run in the debugger it will stop at the Break line. Now imagine if the user typed the following into the watch window
(Func<int>)(() => v2);
In order to properly execute this the debugger (or more appropriate the EE) would need to create a closure for variable v2. This is difficult but not impossible to do.
What really makes this a tough job for the EE though is that last line. How should that line now be executed? For all intents and purposes the anonymous function deleted the v2 variable and replaced it with closure2.v2. So the last line of code really now needs to read
var v3 = closure1.v1 + closure2.v2;
Yet to actually get this effect in code requires the EE to change the last line of code which is actually an ENC action. While this specific example is possible, a good portion of the scenarios are not.
What's even worse is executing that lambda expression shouldn't be creating a new closure. It should actually be appending data to the original closure. At this point you run straight on into the limitations ENC.
My small example unfortunately only scratches the surface of the problems we run into. I keep saying I'll write a full blog post on this subject and hopefully I'll have time this weekend.
Lambda expressions, like anonymous methods, are actually very complex beasts. Even if we rule out Expression (.NET 3.5), that still leaves a lot of complexity, not least being captured variables, which fundamentally re-structure the code that uses them (what you think of as variables become fields on compiler-generated classes), with a bit of smoke and mirrors.
As such, I'm not in the least surprised that you can't use them idly - there is a lot of compiler work (and type generation behind the scenes) that supports this magic.
You can't use lambda expressions in the Immediate or Watch windows.
You can however use System.Linq.Dynamic expressions, which take the form .Where("Id = #0", 2) - it doesn't have the full range of methods available in standard Linq, and doesn't have the full power of lambda expressions, but still, it's better than nothing!
The future has come!
Support for debugging lambda expressions has been added to Visual Studio 2015 (Preview at the time of writing).
Expression Evaluator had to be rewritten, so many features are missing: remote debugging ASP.NET, declaring variables in Immediate window, inspecting dynamic variables etc. Also lambda expressions that require calls to native functions aren't currently supported.
this might help:
Extended Immediate Window for Visual Studio (use Linq, Lambda Expr in Debugging)
http://extendedimmediatewin.codeplex.com/
http://dvuyka.spaces.live.com/blog/cns!305B02907E9BE19A!381.entry
All the best,
Patrick
Lambda expressions are not supported by the debugger's expression evaluator... which is hardly surprising since at compile time they are used to create methods (or Expression Trees) rather than expressions (take a look in Reflector with the display switched to .NET 2 to see them).
Plus of course they could form a closure, another whole layer of structure.
In VS 2015 you can do so now,this is one of the new feature they added.
If you still need to use Visual Studio 2013, you can actually write a loop, or lambda expression in the immediate window using also the package manager console window. In my case, I added a list at the top of the function:
private void RemoveRoleHierarchy()
{
#if DEBUG
var departments = _unitOfWork.DepartmentRepository.GetAll().ToList();
var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList();
#endif
try
{
//RoleHierarchy
foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false))
_unitOfWork.RoleHierarchyRepository.Remove(item.Id);
_unitOfWork.Save();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
throw;
}
}
Where my GetAll() function is:
private DbSet<T> _dbSet;
public virtual IList<T> GetAll()
{
List<T> list;
IQueryable<T> dbQuery = _dbSet;
list = dbQuery
.ToList<T>();
return list;
}
Here I kept getting the following error, so I wanted to print out all the items in the various repositories:
InnerException {"The DELETE statement conflicted with the REFERENCE constraint \"FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId\". The conflict occurred in database \"CC_Portal_SchoolObjectModel\", table \"dbo.Department\", column 'OranizationalRoleId'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException}
Then, I find out how many records are in the department repository by executing this in the immediate window:
_unitOfWork.DepartmentRepository.GetAll().ToList().Count
Which returned 243.
So, if you execute the following in the package manager console, it prints out all the items:
PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i }
The author for the idea can be found here
To answer your question, here's the Visual Studio Program Manager's official explanation of why you can't do this. In short, because "it's really, really hard" to implement in VS. But the feature is currently in progress (as updated on Aug 2014).
Allow the evaluation of lambda expressions while debugging
Add your vote while you're there!

VS cannot show information on variable

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.

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.

Categories

Resources