Is there an easy way to create and Object and set properties in C# like you can in Javascript.
Example Javascript:
var obj = new Object;
obj.value = 123476;
obj.description = "this is my new object";
obj.mode = 1;
try c# anonymous classes
var obj = new {
value = 123475,
description = "this is my new object",
mode = 1 };
there are lots of differences though...
#Valera Kolupaev & #GlennFerrieLive mentioned another approach with dynamic keyword
In case, if you want to create un-tyed object use ExpandoObject.
dynamic employee, manager;
employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
Your other option is to use anonymous class , but this will work for you, only if you would use it in the scope of the method, since the object type information can't be accessed from outside of the method scope.
In C# you could do:
var obj = new SomeObject {
value = 123476,
description = "this is my new object",
mode = 1
};
EDIT: Holding this here pending clarification from OP as I may have misunderstood his intentions.
The way to do this is you use C# 4.0 Dynamic types like Expando Object... see this topic:
How to create a class dynamically
Related
I've have object like this:
object rt = new {
page = 1,
};
Now how could I add new values to this object? I mean something like this:
rt += { code = 5 };
How it could be possible?
It sounds more like you want a Dictionary<string,int>
var rt = new Dictinary<string,int>(){
{"page",1}
};
rt.Add("code",5);
You can also do it with System.Dynamic.ExpandoObject - but this is just a fancy wrapper around a dictionary.
dynamic rt = new ExpandoObject();
rt.page = 1;
rt.code = 5;
Console.WriteLine(rt.page);
Use ExpandoObject
dynamic rt = new ExpandoObject();
rt.page = 1;
rt.code = 5;
The actual question is: why do you need this at all? Imagine your object was a named one, e.g. like this:
var m = new MyClass { MyProperty = ... };
with
class MyClass
{
public string MyProperty;
}
What you want to do is, to add a further property to that class at runtime, which isn´t possible. You can´t do the following:
m.AnotherProperty = ...
as AnotherProperty isn´t defined on that type.
Even declaring m as dynamic wouldn´t help you, as the actual type (MyClass) doesn´t know anything of AnotherProperty.
dynamic a = new MyClass { MyProperty = ... };
a.AnotherProperty = ...;
So the simple answer to your question is: no, you can´t add members to a class at runtime.
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"]);
}
Right now, I'm doing this
var data = new JobDataMap(new Dictionary<string,string> { {"obj", "stringify"} });
But I want to do this:
dynamic d = new { obj = "stringify" };
var data = new JobDataMap(d);
Is there some secret syntactical sugar that would allow me to do this?
There's no magical way of doing this. There's no way the compiler can know that your Dynamic object really is a Dictionary at compile time.
That being said, you could create an extension method that converts it to a Dictionary so that you could do something like this:
dynamic d = new { obj = "stringify" };
var data = new JobDataMap(d.ToDictionary());
This blogpost offers an example: http://blog.andreloker.de/post/2008/05/03/Anonymous-type-to-dictionary-using-DynamicMethod.aspx
I'm trying to dynamically create an object of a certain type in a LINQ-to-XML query based on a string within my XML document. I'm used to being able to dynamically create an object of any type in PHP and JavaScript by simply being able to write something like:
$obj = new $typeName();
Ideally, I'd like to be able to do something like:
List<someObj> = (from someObjs in XMLfile
select new someObj()
{
Name = (string)someObjs.Element("name"),
NestedObj = new someObjs.Element("nestedObj").Element("type")()
{
NestedName = (string)someObjs.Element("nestedObj").Element("name")
}
}).ToList();
I just can't figure out how to do it without grabbing a hold of the current executing assembly.
You can use:
Activator.CreateInstance(Type.GetType(typeName))
Of course, this only works for types with a parameterless constructor.
Update (initializing the object):
You can use C# 4 dynamic typing features to set properties of the newly created object:
dynamic newObj = Activator.CreateInstance(Type.GetType(typeName));
newObj.NestedName = str;
In the context of a LINQ to XML query, you may have to resort to lambda syntax with explicit body:
var list = XMLFile.Select(someObjs => {
dynamic nestedObj = Activator.CreateInstance(
Type.GetType(someObjs.Element("nestedObj").Element("type")));
nestedObj.NestedName = (string)someObjs.Element("nestedObj").Element("name");
return new someObj {
Name = (string)someObjs.Element("name"),
NestedObj = nestedObj
};
}).ToList();
Use the createinstance method of activator class
As the title suggests, I'm tyring to pass a variable data type to a template class. Something like this:
frmExample = New LookupForm(Of Models.MyClass) 'Works fine
Dim SelectedType As Type = InstanceOfMyClass.GetType() 'Works fine
frmExample = New LookupForm(Of SelectedType) 'Ba-bow!
frmExample = New LookupForm(Of InstanceOfMyClass.GetType()) 'Ba-bow!
LookupForm<Models.MyClass> frmExample;
Type SelectedType = InstanceOfMyClass.GetType();
frmExample = new LookupForm<SelectedType.GetType()>(); //Ba-bow
frmExample = new LookupForm<(Type)SelectedType>(); //Ba-bow
I'm assuming it's something to do with the template being processed at compile time but even if I'm off the mark there, it wouldn't solve my problem anyway. I can't find any relevant information on using Reflection to instance template classes either.
(How) can I create an instance of a dynamically typed repository at runtime?
A C# example of something pretty close is located here on a question I had:
typeof(MyClass).GetMethod("Foo").MakeGenericMethod(new[] { param.GetType() }).Invoke(null, new[] { param });
Converting to VB.NET, changing it to type creation not method invocation and using your example names for you:
Dim frmExample as LookupForm<Models.MyClass>;
Dim SelectedType as Type = InstanceOfMyClass.GetType();
Dim GenericLookupType as Type = GetType(LookupForm(Of)).MakeGenericType(SelectedType)
frmExample = Activator.CreateInstance(GenericLookupType, new object(){})
(Ah for some reason I thought you wanted it in VB.NET but here is a C# example)
LookupForm<Models.MyClass> frmExample;
Type SelectedType = InstanceOfMyClass.GetType();
Type GenericLookupType = typeof(LookupForm<>).MakeGenericType(SelectedType);
frmExample = Activator.CreateInstance(GenericLookupType, new object[]{});
Use Type.MakeGenericType.
Type modelType = typeof(Models.MyClass);
var repoType = typeof(LookupForm<>).MakeGenericType(new [] {modelType} );
//at this point repoType == typeof(LookupForm<Models.MyClass>);
var repo = Activator.CreateInstance(repoType );
//Ta-dah!!!
And VB.NET version :)
Dim modelType As Type = GetType(Models.MyClass)
Dim repoType As Type = GetType(LookupForm(Of )).MakeGenericType(New Type() {modelType})
'at this point repoType = GetType(LookupForm(of Models.MyClass))'
Dim repo = Activator.CreateInstance(repoType)
'Ta-dah!!!'
This sounds like a candidate for the Dynamic Language Runtime, 'Dynamic' type in C#, but that would require you to use .NET 4.0
Unfortunately you can't do this without reflection and even then its not very friendly. The reflection code will looks something like this:
Type baseType = typeof(LookupForm<>);
Type selectedType = InstanceOfMyClass.GetType(); //or however else you want to get hold of it
Type genericType = baseType.MakeGenericType(new Type[] { selectedType });
object o = Activator.CreateInstance(genericType);
Of course now you don't know what to cast your object to (assuming selectedType was dynamically set), but you can still call the methods on it via reflection, or you could create a non-generic interface to cast it to & call the methods on that.