Add property to a list? - c#

I have a list with a lot of objects List<MyObjects> - Im iterating through this list and reading the objects. Thats all fine. I just relized now, what it would be awesome if I could add 1 more special value to this List - not an Object, just 1 value of something (a string).
I could now create a class like
class Needless
{
public List<MyObjects> MyList { get; set; }
public string MyValue { get; set; }
}
but Im trying to avoid that. I just really need 1 string with an input every List<MyObjects> Any ideas?

Tuple<string, List<MyObject>> is an option. However, if you are going to use this pairing a lot, I would advise creating a custom class for it to be more explicit - either like you have done, or by deriving List<MyObject> and adding the string as a property.
If you are working "in scope" you could always make anonymous types:
var t = new { TheString = "", TheList = new List<MyObject>() };
var list = t.TheList;
var s = t.TheString;
But this only really has benefit in the scope of a method. The compiler can give IntelliSense for this and it is strongly-typed at compile time.
Or if you really want to go all out, use ExpandoObject from System.Dynamic:
var expando = new ExpandoObject();
expando.List = new List<MyObject>();
expando.TheString = "";
This is typed in-line without any IntelliSense support, and will invoke the DLR. ExpandoObject simply uses an IDictionary<string, object> under the hood, so...
var dict = (IDictionary<string, object>)expando;
...is valid.
The last option is a little tongue-in-cheek. It'll work, but the development experience against it isn't ideal compared to other options. That said, we use ExpandoObject in our test code, but I can't remember why. One can only hope the reasoning was sound, but it was likely a developer getting giddy with new toys...

you can inherit the List and simply add your property, it's a bit cleaner than composite the List inside another class

You could extend a List implementation with your Needless class. That way you can still treat your list as a list.

Related

Is there a way to construct a deeply nested Dictionary with nice syntax and IntelliSense support?

I am trying to create an object that contains the parsed register values of a robot. I have an ASCII text file that contains representations of the variables and arrays. However, I am struggling to think of an easy way to use the deeply nested values. Ideally, the syntax to use the deeply nested objects would be something like Registers["PositionRegister"]["CurrentPosition"]["X_Coordinate"] and the dictionary would be something like this:
(There was a JSON representation here of what I wanted the dictionary to look like, but people kept suggesting JSON serialization...)
However, since I am parsing the file and constructing the object at the same time, I don't know how deep the nesting will go until the parsing is complete.
I've tried using a simple Register class that can contain a dictionary of sub-Registers:
public class Register
{
public Dictionary<string, Register>? subRegisters;
public string name { get; set; }
public string value { get; set; }
}
However, the usage turns into super unintuitive syntax like motionRegister.subRegisters["Register1"].subRegisters["SubRegister1"].subRegisters["Value1"].Value and I'm duplicating information by using the name as the key.
I've also tried using only nested Dictionaries like:
public Dictionary<string, object> CreateRegisters()
{
Dictionary<string, object> TopLevelRegisters = new();
Dictionary<string, object> SubRegisters = new();
Dictionary<string, object> SubSubRegisters = new();
SubSubRegisters.Add("SubSubElement1", "5678");
SubRegisters.Add("SubElement1", "1234");
SubRegisters.Add("SubElement2", SubSubRegisters);
SubRegisters.Add("SubElement3", "1357");
TopLevelRegisters.Add("Register1", SubRegisters);
return TopLevelRegisters;
}
but they end up being super difficult to use since IntelliSense doesn't know what the object will be until runtime. I would return it as another Dictionary, but I don't know how deep the nesting will have to go.
I'm sure that there's a simple solution, but I can't seem to find it.
The closest thing I could come up with is to
Subclass Dictionary<>, and define the subclass in terms of itself (allows for arbitrary depth, and prevents the need for what you call the "unintuitive syntax" of a sub-dictionary manifesting in the path)
Hide the existing indexer with a new implementation (allows for auto-construction of a new level)
Provide a Value property for storing the value of the leaf node.
Provide a ToString() that returns Value (allows for the elimination of .Value from the syntax in certain cases, such as concatenation of strings, WriteLine, etc.)
NOTE: A Name property is dropped altogether because the name can be determined based on the dictionary key.
This code will look something like this
public class RecursiveDictionary : Dictionary<string, RecursiveDictionary>
{
public string? Value { get; set; }
public override string? ToString() => Value;
public new RecursiveDictionary this[string key]
{
get
{
if (!TryGetValue(key, out var subDictionary))
base[key] = subDictionary = new RecursiveDictionary();
return subDictionary;
}
set => base[key] = value;
}
}
During parsing, you only have to output each path to a terminal Value or if you keep track of where you're at in the parsing, simply set the Value of the current (sub)dictionary. (Side note, it doesn't matter how you build it or whether the source is proprietary (your case), JSON, or some other format).
Here's an example construction:
var rd = new RecursiveDictionary();
rd["x"].Value = "Hi!";
rd["x"]["y"].Value = "VALUE";
rd["a"]["b"]["c"]["d"].Value = "VALUETWO";
Notice, I didn't have to allocate RecursiveDictionary for every level; this is because the get portion of the indexer does that for me.
From the static Intellisense (i.e. while program is not running), you can hover over rd and see it is a RecursiveDictionary,
hover over Value and see that it is a string,
and hover over one of the ] or [ and see that it is an indexer on the dictionary:
Now for the dynamic (runtime under debugger) I'm not going to show all the code for various accesses or the Intellisense for it, but I can emulate both in a watch window. What you see in the watch window below could just as easily been lines of Console.WriteLine(...) with you hovering over the various locations. So imagine these examples:
CAVEAT: The ToString() might give you some unexpected results depending on the situation. Are you concatenating strings, are you viewing in the debugger, are you using in a WriteLine(), are you passing a sub-dictionary to another method, etc. If that becomes problematic, then go for a slightly less terse syntax that requires you to always get the value explicitly via the Value property.

Basic C# lists - Adding an unknown number of items

I am teaching myself C# and modern Windows programming in general and had a question about lists in C# that I haven't found an answer for. The reference book I am using seems to indicate that in C# before you can assign a variable to a list, you need to define a new variable for each item in the list and assign it's value.
I am trying to write a simple program that will let me write text notes, assign keywords to them, and them filter the resulting group of notes based on the keywords I select. From what I can figure out, a List seems the best mechanism in C# to do this since there will be an unknown number of notes. However, I am struggling with the idea of defining a unknown number of variable names ahead of time to store the notes in, to add to the List.
Am I looking at the wrong construct in C# for this, misunderstanding what is required to assign a variable value to a List, or lacking knowledge of some mechanism for auto-creating variables and variable names that can be leveraged as part of a list? Something else?
Sorry if this is too simple a question for SE crowd, but this seemed like the best place to ask.
A List<T> is a data structure that lets you store an unknown number of T, but you don't need variable names for the elements of the list - just for the list itself.
Is this what you need?
var notes = new List<string>()
{
"This is a note.",
"I am happy",
};
notes.Add("This is another happy note");
notes.AddRange(new [] { "Another happy notes", "This is also a note", });
var selected = notes.Where(n => n.Contains("happy")).ToList();
The values in selected are:
"I am happy", "This is another happy note", "Another happy notes"
I am not sure what exactly is your confusion. But it sounds like you are having issues in constructing class or using C# types. To keep it simple for now you can follow something in this manner.
// This represents individual note
public class Note
{
// Initialize keywords list in constructor
// in order to avoid Null reference exception.
public Note() {
Keywords = new List<string>();
}
public string Title { get; set; }
public string Content { get; set; }
public List<string> Keywords { get; set; }
}
// In main code, you can simply have List<Note> to hold collection of any no of notes.
// Also, when user adds a note you will create a new Note instance and add to collection.
List<Note> notes = new List<Note>();
Note newNote = new Note();
newNote.Title = "Note 1";
newNote.Content = "Note 1 Content";
newNote.Keywords.Add("Test1");
notes.Add(newNote);

NancyFx DynamicDictionary

I am trying to understand the DynamicDictionary in NancyFX, it looks pretty cool. Does anyone know of a blog post or similar, that goes through the internals of it?
I need a propertybag to pass around objects, that I don't know the content of because they come from outside my system as JSON. But based on the contents of these objects, such as the presence of certain properties I need to do stuff.
I could just pass around dynamic objects, but that is a bit too vague I think. Don't really like that.
I would need nested dictionaries, to fully represent the object graph.
The dynamic dictionary is just a ExpandoObject with a Dictionary in it. So it can still be accessed like a dictionary.
For example, in MVC you access Form properties like so:
var name = Request["name"];
or
var name = Request.Form["name"];
When a request comes into Nancy you can access it via the dot notation. Or via the class indexer.
var name = parameters.name;
var name = parameters["name"];
This is handy when you're sending query string or form names that have values that cannot be used in dot notation.
var firstName = parameters["first-name"];
The values are also dynamic, so it could be made up of nested objects. This allows you to do stuff like:
var firstName = parameters.contact.firstname;
So if you're passing a JSON payload to the request then you can access the entire structure using dot notation.
However you will probably find most developers using Nancy only ever access Route values or QueryString values using this method.
Get["/products/{id:int}/"] = parameters => {
int id = parameters.id;
};
So back to the original question:
Is there a blog post or any doco: Nope.
Why does it exist: For sugar syntax.
Can I use it for what I want: Yes absolutely!
Can you tell me how to use it: Nope, however it shouldn't be hard. Just look the model binding in Nancy to figure it out. It's not too hard.
Just an edit based on the answer by the OP.
When you access the dot notation, continued dot notation will only work on further dynamic types.
This means using var will cause an exception because of the way var and dynamic are handled by the compiler.
When you do:
var person = parameters.person;
var name = person.name;
parameters is currently dynamic and implements TryGetMember, this internally looks up a dictionary of values and attempts to return the value.
When you define the object as var for the person variable. The compiler assumes that anything after that exists on the object, so it looks for name on the person variable.
Since name does not exist as a member of person it will throw.
To resolve this, the variable must be assigned as dynamic. So the example becomes:
dynamic person = parameters.person;
var name = person.name;
This will work.
So I started working with the DynamicDictionary and it is pretty cool and easy to work with. Only one thing bugs me right now. That is if I nest DynamicDictionaries.
Look at the following example:
private void TestNestedDynamicDictionary()
{
dynamic dictionary = new DynamicDictionary();
dynamic nestedDictionary = new DynamicDictionary();
nestedDictionary.Add("name", "Peter");
dictionary.Add("person", nestedDictionary);
var person = dictionary.person;
var name = person.name;
Console.WriteLine(name);
}
This fails when trying to access person.name with a 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
DynamicDictionaryValue' does not contain a definition for 'name'
If I just do an explicit cast like this it works.
var person = (DynamicDictionary)dictionary.person;
Any input on how I could make it behave as DynamicDictionary right out of the box... apart from checking the DynamicDictionaryValue before it is returned, and do the cast there, which I think is messy.
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object value;
if (!dictionary.TryGetValue(binder.Name, out value))
{
result = new DynamicDictionaryValue(null);
return true;
}
var dictVal = value as DynamicDictionaryValue;
if (null != dictVal && dictVal.Value is DynamicDictionary)
{
result = dictVal.Value;
}
else
{
result = value;
}
return true;
}

Converting a KeyValuePair collection in to anonymous type

Is it possible to convert a a IEnumerable<KeyValuePair<string,string>> of KeyValuePair to an anonymous type?
Dictionary<string, string> dict= new Dictionary<string, string>();
dict.add("first", "hello");
dict.add("second", "world");
var anonType = new{dict.Keys[0] = dict[0], dict.Keys[1] = dict[1]};
Console.WriteLine(anonType.first);
Console.WriteLine(anonType.second);
********************output*****************
hello
world
The reason i would like to do this is because I am retrieving an object from a webservice that represents an object that does not exist in the wsdl. The returned object only contains a KeyValuePair collection that contains the custom fields and their values. These custom fields can be named anything, so i cant really map an xml deserialization method to the final object i will be using (whose properties must be bound to a grid).
*Just because I used Dictionary<string,string> does not mean it is absolutely a dictionary, i just used it for illustration. Really its an IEnumerable<KeyValuePair<string,string>>
Ive been trying to thing of a way to do this, but am drawing a blank. This is c# .NET 4.0.
You could use the ExpandoObject, it is based on a dictionary.
I think there are a lot of ways to achieve this, but actually converting it in the same Dictionary seems a bit odd to do.
One way to accomplish this, by not actually converting everyting is the following:
public class MyDictionary<T,K> : Dictionary<string,string> // T and K is your own type
{
public override bool TryGetValue(T key, out K value)
{
string theValue = null;
// magic conversion of T to a string here
base.TryGetValue(theConvertedOfjectOfTypeT, out theValue);
// Do some magic conversion here to make it a K, instead of a string here
return theConvertedObjectOfTypeK;
}
}
ExpandoObject is the best option, which I believe is a wrapper around some XML. You could also use an XElement:
var result = new XElement("root");
result.Add(new XElement("first", "hello"));
result.Add(new XElement("second", "world"));
Console.WriteLine(result.Element("first").Value);
Console.WriteLine(result.Element("second").Value);
foreach (var element in result.Elements())
Console.WriteLine(element.Name + ": " + element.Value);
I haven't used ExpandoObject, so I'd try that first because I understand it does exactly what you want and is also something new and interesting to learn.

What are the benefits of implicit typing in C# 3.0 >+

The only advantage I can see to do:
var s = new ClassA();
over
ClassA s = new ClassA();
Is that later if you decide you want ClassB, you only have to change the RHS of the declaration.
I guess if you are enumerating through a collection you can also just to 'var' and then figure out the type later.
Is that it?? Is there some other huge benefit my feeble mind does not see?
It's mostly syntactic sugar. It's really your preference. Unless when using anonymous types, then using var is required. I prefer implicit typing wherever possible though, it really shines with LINQ.
I find it redundant to type out a type twice.
List<string> Foo = new List<string>();
When I can easily just type var when it's obvious what the type is.
var Foo = new List<string>();
var is useful for anonymous types, which do not have names for you to use.
var point = new {X = 10, Y = 10};
This will create an anonymous type with properties X and Y. It's primarily used to support LINQ though. Suppose you have:
class Person
{
public String Name {get; set;}
public Int32 Age {get; set;}
public String Address {get; set;}
// Many other fields
}
List<Person> people; // Some list of people
Now suppose I want to select only the names and years until age 18 of those people who are under the age of 18:
var minors = from person in people where person.Age < 18 select new {Name = person.Name, YearsLeft = 18 - person.Age};
Now minors contains a List of some anonymous type. We can iterate those people with:
foreach (var minor in minors)
{
Console.WriteLine("{0} is {1} years away from age 18!", minor.Name, minor.YearsLeft);
}
None of this would otherwise be possible; we would need to select the whole Person object and then calculate YearsLeft in our loop, which isn't what we want.
I started what turned out to be a hugely controversial thread when I first signed on here (my choice of "evilness" to describe general use of var was obviously a terrible choice.) Needless to say, I have more appreciation for var than I did before I started that thread, as well as a better understanding of how it can be usefully used:
The evilness of 'var' in C#?
Some good reasons to use var:
Brevity
Reduction of Repetition (DRY)
Reduced refactoring effort
Supports anonymous types (key reason it was added to C#)
Have a look at this questions. Maybe they'll help you decide.
Use of var keyword in C#
https://stackoverflow.com/questions/633474/c-do-you-use-var
It allows me to not repeat myself unnecessary. Consider this:
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
We have a very long typename repeated twice on the same line twice with absolutely no benefit. Furthermore, if you ever need to refactor this, you'll need to update the type twice. Whereas this is just as expressive:
var dict = new Dictionary<string, List<int>>();
There's still no doubt about type of dict here, but the code is shorter, and I would claim that it is easier to read as well.
Actually "var" in C# is used to deal with anonymous type.
Like:
var t = new {number = 10, name = "test"};
The overarching reason for the implicit typing was to support anonymous types, like those produced by LINQ queries. They can also be a big benefit when dealing with complex-typed generics...something like Dictionary<int,List<string>>. That's not too complex, but imagine enumerating...
foreach KeyValuePair<int,List<string>> pair in myDictionary
{
}
is simplified with implicit typing.
While the var keyword was primarily introduced to support anonymous types, the main argument I've seen for using it more widely is for brevity/more readable code, plus fitting more on your line of code:
Dictionary<string, double> data = new Dictionary<string, double>();
versus
var data = new Dictionary<string, double>();
Though not a good reason for most people, I also like the var keyword as a blind programmer, as I listen to the code being read out and thus here the variable name after just one syllabul :-)

Categories