System.Collections.Generic.List<T> debugging in quick watch - c#

I have a simple class called SSR2 with one property.
public class SSR2
{
public string SSRs { get; set; }
}
in another class I am instantiating a list of SSR2 and add a new item to it. everything works fine and compile correctly, but int the quick watch something weird happens, or I am missing something. There are two properties which I never seen before : "Capacity" and "Count", and the capacity is set to 4, 3 of them are null.
Why am I getting this behavior ? normally I am expecting a list with direct access to members like below :
Thank for your help.

I had the same problem, I fixed it by going to Tools>Options>Debugging>General in Visual Studio, and unchecking "Show raw structure of objects in variables windows".
By unchecking this box you should see the elements of the list as in your second screen shot.

A list is using an array, but abstracts you from the details. It still has a size, and needs to know how many items it has, so when you approach the mad, it can allocate more space for it.
So, having a list of one item is silly, since the next time you want to add you'll have to cart a bigger array.
I guess it creates the allocation for four items, and grows as needed later.

Related

Why can't Json.Decode handle arrays in C#?

Could someone help shed light on what is going on here?
If I do this in a C# program:
dynamic data = Json.Decode("{\"myObjects\": [ { \"id\": 1 }, { \"id\": 2 } ] }");
int id = data.myObjects[0].id;
I am able to access id and it is set to 1... everything is fine up until this point.
What I don't understand is why, when I'm debugging the program, I cannot view the contents of datain the Locals inspector. Instead it tells me this, as if it doesn't know how to process the array.
Error No further information on this object could be discovered
'data' is declared as dynamic type and thats why you cannot mouse over and see the value. You could still see the value if you add 'data' to Watch.
There seems to be a bug/limitation of Visual Studio (at least the 2013 version I use). If you put a watch on data, you can click on Dynamic View and see that it has stuff, but if you click on myObject (that is a DynamicJsonArray) you only get its "dynamic" part, and not its "fixed" properties (like the Length) and if you try to click on its Dynamic View you receive No further information on this object could be discovered... but if you create a watch for data.myObject, then you'll still have the unusable Dynamic View, but you can look at the "fixed" properties of the DynamicJsonArray (like the Length) and if you click on the Result View you can see the items of the array. See image:
The other answers did not work for me, but I found an alternative way to view the array contents in Visual Studio.
I have found that we can see the contents of the DynamicJsonArray in the Watch window (or IntelliSense), by looking inside the Non-Public members of the top level object. Inside that, we see the private _values member and inside that, we see the values. Upon opening the relevant value, we see the Key and Value members inside.
We can then proceed to open the Value node and then, the Results View, which will show the items in the array. We can then finally access the individual items in the collection

Declaring a property with an empty set in C#

I am using entity framework database first and extending the AutoGenerated partial classes. Is the following alright if I need to also set the property in my application based on certain scenarios? It just feels strange because I am usually setting a private property in my set, but don't think I need to here with EF.
public string FullName
{
get
{
return string.Format("{0} {1}", FirstName, LastName);
}
set
{
}
}
In my application FullName is a bound field in a grid. When I bind the grid from the database it works fine as a read-only property. But there is an instance where I have to dynamically create an objectlist of CustomerContact and pass it to another page in a Session variable and bind the grid in memory on the new page. Since the bound field for the same column in the grid on the new page needs to be FullName it seems like I have no option but to allow a Set on this property...
Based on the comments. No you should not leave it empty.
Think about it from a user point of view.
You can say MyThingy.FullName = "Fred Blogs". It compiles, it throws no exceptions and does absolutely nothing.
Other people's code, which includes your own in a couple of months, is hard enough to understand without drilling big holes in your cortex before you start.
To beef up from your last comment. No it doesn't make sense to have one class that has two completely different behaviours. There are lots of ways to deal with this sort of scenario, but making one object that implements both behaviours poorly isn't a good choice.
Hard to say which option would be best, but a DTO (Data Transfer Object) with a converter from and perhaps to the EF representation would be a much better solution than leaving a huge hole in the logic to fall into later.

The efficient way to make external data structure updater UI

I have a class contains a lot of properties. One of them needs a special UI to be edited.
The user may press edit to this property in the UI then he make changes and either press OK or Cancel
e.g.
class A{
private List<Employee> employees;
public void EditMyEmployees(){
EmployeeEditorForm editor = new EmployeeEditor(employees);
if(editor.ShowDialog() == DialogResult.OK){
employees = editor.GetEditedEmployeesList();
}
}
}
The problem in the previous code that the editor has a copy of the reference to the employees List
and when the editor makes any edits in the List it will be reflected in the original object.
So, pressing OK or Cancel will have the same effect (the object is already updated) and no need for the step
employees = editor.GetEditedEmployeesList();
I know that making deep copy for the employees array before sending it to the editor will solve the problem but still I think this is not the efficient way to do it
I am looking for a design pattern that can make this in a better way.
You don't necessarily need to deep copy the whole collection. You just need to keep track of the elements that changed. Within your EmployeeEditor, use three lists (List<Employee> to keep track of:
Added employees
Removed employees
Changed employees
Upon Cancel, you would need to remove the "added" items, add back the "removed" items, and replace the changed items with their original state.
Note that the changed employees list would need to keep a copy of the original state of the object. If the Employee class has some sort of unique id, you can match cased on that id. Otherwise, the "changed" list would need to be a List<Tuple<Employee, Employee>> so that you can store the matching items.
Also note that, when changes happen in the employees list, you also need to make necessary changes in those three lists. For example, if an new employee is added and then removed, you also need to remove that record from the "added" list. Or it is possible an employee is changed and then removed, in which case you also need to remove from "changed" list.
Having said all this, if I were you, I would make a decision based on the expected use cases and real performance problems (not anticipated performance issues). It is very likely that simply deep copying your collection is the simplest and least error prone way.
There are two kinds of changes involved here: (1) changes to the list (Add / Remove) and (2) changes to individual elements of the list (employees in this case).
Now, part of the problem comes from the semantics of OK/Cancel. If you restrict the scope of these two buttons to changes of the second kind (i.e., changes to the elements of the list), you will be able to handle Remove with a confirmation dialog on this particular action ("Remove such and such"?). For the Addition you don't need anything special, just add a new element to the list. If the user changes their mind they will still have the Remove action available.
For changes on a particular element (second kind) you can use the command pattern as mentioned in the comment. More simply, you could initialize temporary variables for all the fields your editor displays from the element under edition. As the user modifies some values your editor will update the corresponding temporaries. If the user press Cancel you will simply forget those changes (or reinitialize them from the element). If the user press Apply (yes, you should include the Apply button also,) you will now write each of the temporary values onto the corresponding element's attribute. If the user hits OK you would Apply and Close.

C# SQL CLR Project - Public Generic.List items show up as non-public members in debugger

I'm having an issue in a C# SQL CLR project where publicly declared Generic.List items are not showing up as public in the debugger. This is problematic because I'm trying to serialize the object to XML. The real project has some complex objects, but a very simple example would be something like this:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void DoSomething()
{
// the Thing Object has a public property of List<string>
// that is created in the constructor
Thing t = new Thing();
t.Items.Add("test");
t.Items.Add("test2");
// now, if I look at t in the debugger, it has given the
// items list a capacity of 4 and shows the items as
// non-public members (2 with values and 2 that are null)
}
I wanted to post an image from the debugger here, but it appears I cannot do that as a new user...
With all of that said, is this behavior because it is a SQL CLR project? The same code worked fine when developing in a console application (though I guess I could have messed something up when adding it to the CLR project).
Adding additional detail on the Thing object - it includes the following declaration for the Items:
public List<string> Items { get; set; }
Then, in the debugger, the Items just shows Capacity and Count (no actual items or properties for the Items). The actual item instances are listed under Non-Public members.
The Items property itself can never be seen by a debugger, because it is an indexed property, so there isn't a value you can just get for it, and hence examining the value it returns doesn't make sense (like examining the 30th of February or a politician's kept promises; it just doesn't exist).
List<T> uses the DebuggerTypeProxyAttribute attribute to define another class to be used to give a debugger eye view. This class (one internal to mscorlib) has a public Items property that returns an array with a copy of the list's items, so that it looks like you can actually examine the Items property of List<T> when really you are examining the Items property of an object that copies out the items when invoked.
Debuggers don't have to use this approach, so maybe the one you are using doesn't, or there's some other restrictions, but if you are using a debugger that doesn't support DebuggerTypeProxy you can just examine the private member that stores the items in an array (the array will be at least as large as Count, and possibly a bit larger to leave growing room rather than resizing on each Add; you can ignore elements beyond Count - 1).
This has nothing to do with XML serialisation, so whatever problem you are having with that is likely completely unrelated.
Edit:
I see some people are having other problems with XML serialisation and the SQL CLR as per these:
SQL Server not finding serialization assembly
http://connect.microsoft.com/VisualStudio/feedback/details/753005/when-deploying-a-sqlclr-assembly-with-a-generated-xmlserializer-assembly-the-xmlserializer-assembly-should-be-deployed
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/3fa5dce3-b0f3-44f8-9b7b-65439f1c98ae/cannot-deploy-xmlserializers-clr-assemblies?forum=ssdt
http://social.msdn.microsoft.com/Forums/sqlserver/en-US/e6560fa4-76f1-4da2-b795-7926d0743baa/sql-clr-problem-with-xmlserializer?forum=sqlnetfx
Your XML problem is indeed different to your debugger view issue. (I meanwhile am off to add debugger proxies to some of my collection types, I've always figured people would just skip through to the inner members and not care, but you've made me rethink that one).

Downcasting in C#

I'm facing a problem that I don't know how to solve and am hoping the community can help.
I'm writing an app that manages "Lead" objects. (These are sales leads.) One part of my program will import leads from a text file. Now, the text file contains lots of potential leads, some of which I will want to import and some of which I won't.
For ease of programming (and use), I'm parsing the text file into a List<Lead> object, and using a DataGridView to display the leads by setting the DataSource property of the DataGridView.
What I want to do is add a column to the grid, called "Import," with a checkbox that the user can check to indicate whether or not each lead should be imported.
My first thought is to derive a class from Lead:
public Class LeadWithImportCheckbox : Lead
{
bool bImport = false;
public bool Import
{
get { return bImport;}
set { bImport = value;}
}
}
However, the parsing engine returns a list of Lead objects. I can't downcast a Lead to a LeadWithImportCheckbox. This fails:
LeadWithImportCheckbox newLead = (LeadWithImportCheckbox)LeadFromParsingEngine;
This is an invalid cast.
The other option I see is to create a constructor for LeadWithImportCheckbox:
public LeadWithImportCheckbox(Lead newlead)
{
base.Property1 = newlead.Property1;
base.Property2 = newlead.Property2;
....
base.Property_n = newlead.Property_n;
}
This is problematic for two reasons. One, the Lead object has several dozen properties and writing this constructor is a PITA.
But worse, if I ever change the underlying structure of Lead, I need to remember to go back and change this constructor for LeadWithImportCheckbox. This is a danger to my code maintenance.
Is there a better way of accomplishing my goal?
or, to avoid the PITA aspect, use reflection... (try this...)
EDIT: use property, not Field as I had originally written...
public class NewLead : Lead
{
public bool Insert;
public NewLead(Lead lead, bool insert)
{
Insert = insert;
foreach (PropertyInfo pi in typeof(Lead).GetProperties())
GetType().GetProperty(pi.Name).SetValue
(this, pi.GetValue(lead,null), null);
}
}
public class LeadListItem
{
public Lead Lead { get; set; }
public bool ShouldImport { get; set; }
}
i.e. don't copy the Lead object's contents, just store a reference to it in a new LeadListItem object, which adds extra info "outside" the original object.
If you want the properties of Lead to appear in the grid, there is almost certainly a way of doing that. Why not ask that question, instead of downvoting me for telling you the right answer to this question!
A couple options you might have missed:
You could update the Lead object itself to have an Import property (that defaults to false).
You could have your "ImportLead" object treat the Lead as payload (even make it generic, if you want), so you don't need the big constructor.
Build a new Lead object list or enumerable that only contains the objects you want to import in the first place.
You can only downcast, if the object to be downcast is really an object of that type.
An easier way to solve your problem would be to have a DisplayLead class, such as:
public class DisplayLead {
Lead lead;
bool bImport;
}
which would also help you separating stored data from their representation in a GUI.
What you want to do is display the checkbox column on your grid and not have it related at all to your Lead objects. You use the marked columns (and possible the original List) to build a new set of List which will be your import list.
Then handle whatever you wish to do with the newly created List.
Edit: One thing to be careful of when working with lists is the fact every class object is actually only a pointer to the class so if you work with the original list and do something like:
List<Lead> Importable = new List<Lead>();
for(int i=0, i++, i<viewGrid.Count)
if(viewGrid[i].CheckedColumn.Checked)
Importable.Add(OriginalList[i]);
That objects will exist in both lists and if you edit data of a Lead on either list both will be changed.
I cannot downcast to something it is not. If the object was instantiated as a Lead, then it can't be downcast to any derived class. If it were instantiated as a LeadWithImportCheckbox and then returned to your code as Lead, then you can downcast it.
Protip: Check type at runtime with is operator.
There are many ways to do this, but the "right" way pops out because of what you said, here:
For ease of programming (and use), I'm
parsing the text file into a
List object, and using a
DataGridView to display the leads by
setting the DataSource property of the
DataGridView.
What I want to do is add a column to
the grid, called "Import," with a
checkbox that the user can check to
indicate whether or not each lead
should be imported.
Your Lead object stands well on its own, and you want to attach some metadata to it -- you don't want to create another Lead classification (i.e. the LeadWithImportCheckbox class).
So, the best approach in your case is to have a class like so:
public class LeadInfo
{
private Lead lead;
private bool shouldImport;
public LeadInfo(Lead lead)
{
this.lead = lead;
this.ShouldImport = false;
}
public bool ShouldImport
{
get { return shouldImport; }
set { shouldImport = value; }
}
}
This will scale well when you want to add more metadata to your list, like if you want to send yourself email reminders about them every week.
I've seen the correct solution listed so many times I feel like a heel posting it again, but the best way to approach this is to write a wrapper for the Lead object that includes the import flag.
If the properties of the Lead object don't appear in the GridView because you're databinding to the object, then write passthrough properties that mirror the Lead properties on the wrapper object.
The issue is that you want something displayed to the user that isn't an inherent part of the data model. The answer is to wrap the data before presenting it to the user so you can control what they see without changing the underlying model.
If you're concerned that the Lead object will change so many times in the future that changes to the wrapper will be cumbersome, you could look into dynamic code generation based on the Lead object that will automatically generate a wrapper object with the same fields as the Lead object plus the import flag. Though frankly, that's a lot more work than you'll probably need for something as straightforward as this.
As a quick and dirty solution, you can create your 'checkbox' object as a different object that contains an instance of Lead.
public GridLead {
public bool Import { get; set; }
public Lead Lead { get; set; }
}
This way you can easily add more 'grid' properties to this object, while still always retaining a reference to the Lead details without hardcoding property cloning into it.
Recommend you try modifying (upgrading) your imported lead objects.
Try starting with the examples here...
If your Lead class had a copy constructor (e.g. "Lead(Lead otherLead)"), LeadWithImportCheckbox would inherit that and you could just call the base Lead constructor in the LeadWithImportCheckbox constructor - hence no need for LeadWithImportCheckbox to be aware of the details of Lead.

Categories

Resources