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 };
Related
Is there a way for me to read a property value I defined already in an anonymous object while creating the object?
here is an example
var a = new { PropA = "something", PropB = this.PropA + " and another thing"}
Perhaps defining it in a variable right before the declaration of a would work?
var somethingValue = "something";
var a = new { PropA = somethingValue , PropB = somethingValue + " and another thing"}
Otherwise, I don't think you would be able to. You have yet to instantiate the object so this.PropA wouldn't work. To further elaborate, your question was "Is there a way for me to read a property value I defined already in an anonymous object while creating the object?" which doesn't entirely make sense, because you are creating the anonymous object, so the value isn't already defined in the object.
Using dynamic binding can be helpful:
dynamic myObject = a;
myObject.PropB = ... //you can access any property that you know it exists
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.
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;";
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.