how to add an item to an object initialized with:
object obj = new { blah = "asdf" };
If I want to add another key value pair, how would i?
You can't modify the object's anonymous type definition once you make the object using that initializer syntax. That is, once you initialize it with { blah = "asdf" }, it only has that blah property. You can't add another. This is because anonymous types are static types.
The ExpandoObject answers work though, for a dynamic object. See the other answers for that.
If you're really just trying to manage a collection of key-value pairs (kinda sorta based on the way you phrased your question), use a dictionary.
var kvp = new Dictionary<string, string>
{
{ "blah", "asdf" }
};
kvp.Add("womp", "zxcv");
#BoltClock is right on. Another alternative is to use an ExpandoObject, at the loss of intellisense.
dynamic obj = new ExpandoObject();
obj.blah = "asdf";
// sometime later
obj.somethingelse = "dfgh";
// obj now has 'blah' and 'somethingelse' 'properties'
Once you define an object like that, you're done. You can't add anything to it.
If you're using C# 4.0, though, you could always use a dynamic type:
dynamic obj = new ExpandoObject();
obj.blah = "asdf";
obj.blahBlah = "jkl;";
Related
In PHP we can remove one property and its value from the object simply with this code:
$foo->bar = "Something";
unset($foo->bar);
I want to do this in C#.
Imagine that the object is:
var a = new {foo = bar, one = "one"}
How I can remove foo from the object?
Types are defined at compile-time, so there's no removing of properties, not in c#. An anonymous type is a type just like classes that you create; it's just that the name is hidden from you.
The closest you can get to your answer is to define a new type that omits the property you wish to remove:
var b = new { one = a.one };
I want to avoid using the specific type (forgort how I did it before)
var obj = new List<Category>();
obj = (List<Category>)EasyCache.Instance.Item(cacheKey)
Something like: obj = (obj.GetType()???)EasyCache.Instance.Item(cacheKey)
If you don't want to repeat the type name in the assignment you can just combine the declaration and the assignment:
var obj = (List<Category>)EasyCache.Instance.Item(cacheKey)
Note that the empty List<Catgeory> you create is thrown away since you overwrite it in the next line. It seems like you create a new one just to allow the use of var in the declaration.
var and dynamic are great tools, but they should not be used to replace static type checking.
You could use
obj = (dynamic)EasyCache.Instance.Item(cacheKey);
It's not a good way, but it should work.
I have a 'Profile' object/class with an IList of 'Addresses', of which, I will only know their type [profile / addresses] at runtime via GetType() / GetProperties() etc., though I wish to .Add to this list e.g.:
var profile = session.Get<ProfileRecord>(1);
dynamic obj = new ExpandoObject();
obj = profile;
obj["Addresses"].Add(addressNew);
This does not work due to:
Cannot apply indexing with [] to an expression of type
'Test.Models.ProfileRecord'.
I've been looking at IDictionary, but have been unsuccessful in my attempts, nor even know if I should be heading down that path - so what is the correct way to go about this? This entire concept is new to me, so please don't over assume my capabilites ;) Many thanks in advance.
You could do it like this if you dont know the type of profile.
var prop = profile.GetType().GetProperty("Addresses").GetValue(profile);
prop.GetType().GetMethod("Add").Invoke(prop, new object[] {1}); // Add the Value to the list
But then you must be sure the List is already initalized.
But i think you should be able to cast your object and set the Property directly like:
if(profile.GetType == typeof (ProfileRecord))
{
var record = (ProfileRecord)profile;
if (profile.Addresses == null)
{
profile.Addresses = new List<Address>();
}
prfile.Addresses.Add(addressNew);
}
I search on Google but the result is misunderstand.
This is a code flow:
public class Store
{
public dynamic GetList(List<string> propertyFields)
{
// Body here
// for in list propertyFields. Such as: ["Code", "Name", "Address", ...]
// dynamic result = ...
// result.Code = "value", result.Name = "abc", result.Address = "homeless", result.... = "..."
// return result
}
}
Method returns a dynamic object.
propertyFields is a list of fields name. When I pass 4 strings in list, dynamic has 4 property fields with value (later).
When I call this method:
Store store = new Store();
var rs = store.GetList(["Code","Name","Address"])
Console.WriteLine(rs[0].Code)
That is my point.
My question: Is it possible to do that in C#?
You have confused dynamic, which is a compiler feature that means "defer type analysis of uses of this object until runtime" with ExpandoObject which means "an object that can have properties added at runtime".
It is an understandable confusion; many languages that lack static type checking also have expando objects.
You need to take a look to ExpandoObject class.
Here is more detailed answer to your question:
Dynamic class creation
What are the true benefits of ExpandoObject?
I was trying to create objects at runtime. We have .net framework provided classes like DynamicObject and ExpandoObject. Is it possible to create a dynamic object like this
dynamic obj = new expandoObject();
obj["propName1"] = "name"; //string type
obj["propName2"] = 24; //int type
I dont know the property names until runtime. Is it possible to do this way?
Well, two things.
First, yes, you can stuff values into the ExpandoObject object using "property names" contained in strings, because it implements IDictionary<string, object>, so you can do it like this:
void Main()
{
dynamic obj = new ExpandoObject();
var dict = (IDictionary<string, object>)obj;
dict["propName1"] = "test";
dict["propName2"] = 24;
Debug.WriteLine("propName1=" + (object)obj.propName1);
Debug.WriteLine("propName2=" + (object)obj.propName2);
}
Notice how I use the property syntax to retrieve the values there. Unfortunately, dynamic is like a virus and propagates, and Debug.WriteLine is none too happy about dynamic values, so I had to cast to object there.
However, and this is the second thing, if you don't know the property names until runtime, those last two lines there won't appear anywhere in your program. The only way to retrieve the values is again to cast it to a dictionary.
So you're better off just using a dictionary to begin with:
void Main()
{
var obj = new Dictionary<string, object>();
obj["propName1"] = "name";
obj["propName2"] = 24;
Debug.WriteLine("propName1=" + obj["propName1"]);
Debug.WriteLine("propName2=" + obj["propName2"]);
}