is it possible to create a property on a type at runtime? My type "Account" has a predefined bunch of properties such has "ID" and "Account Name" and it implements INotifyPropertyChanged, I wanted to add properties to this type at runtime, so a getter and a setter and the setter would call a method Notify passing in it's property name i.e
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
Yes, but not with "normal" CLR types. You can achieve that, actually that type was created especially for functionalities like that: DynamicObject
Look on example code provided of the class that implements DynamicObject, like
public class DynamicDictionary : DynamicObject
{
...
}
and after you are able to use it like:
dynamic person = new DynamicDictionary();
// Adding new dynamic properties.
person.FirstName = "Ellen";
person.LastName = "Adams";
You can use Reflection.Emit to dynamically create new classes that inherit from your class, and then add the properties to that new type.
As it inherits your own type, it can be considered as being an "extension" for that type.
I must warn you that this path is a complicated one, and you will probably produce code that you will never understand again after finishing the job!
Also you will have understand how MSIL code works. It is a bit odd, and inverted thing. You have to do things quite the oposite way you would expect in a language such as C#. You must push and pop values from stacks to pass as argument to a function, and you must activelly discard unused return values from functions... and so on.
And YES, I am trying to make you afraid of this... it is such a painful way ;)
Consider other alternatives before falling to this one.
There is a lot of material in SO already on this matter: https://stackoverflow.com/questions/tagged/reflection.emit
CodeProject article explaining Reflection.Emit:
Dynamic Type Using Reflection.Emit
Either you use a Dynamic Object or extend behavior via Extension Methods. I don't know of other options.
no, that is not possible with c# objects
you can make dictionary like classes, which can store different properties like in the question with the DynamicObject
what you can do is is creating new class types by reflection, and they can contain new properties. but there is no easy way to access these
Related
I have the class Columns which is derived from List<Column>. I want to populate the class inside one of its methods named GetColumns(). But I'm having trouble doing this. Maybe I'm missing something very very obvious here.
What I'm trying to do is to define Collections as classes that derive from `List and I want to extend these classes to populate them and other stuff.
public class Columns : List<Column>
{
public void GetColumns()
{`
this = Building.PColumns;
}
}
You can't assign to this in a class. (You could do so in a struct.)
Instead of:
this = Building.PColumns;
Try:
this.Clear();
this.AddRange(Building.PColumns);
If you're extending List you should just be able to call all the usual methods ie (add, addrange, remove etc..). Personally I would either extend IEnumerable or use Columns as a wrapper class with a member of type List but each to their own and it of course depends on what you're doing. Especially since you know the type of the list beforehand and you're handling the login in internal functions anyway, i would just have it as a member.
Change the body of the method GetColumns. It is a bit unclear where Building.PColumns is defined. In neither case the this pointer can be reassigned. Furthermore, the name GetColumns suggests that something is returned. However this is not the case as its return type is void. Change the return type of GetColumns to the type of Building.PColumns and return Building.PColumns.
I have two classes like this:
public abstract class MyBase
{
protected MyBase(){
Initialize();
}
protected IDictionary<string,string> _data;
private void Initialize() {
// Use Reflection to get all properties
// of the derived class (e.g., call new MyDerived() then
// I want to know the names "Hello" and "ID" here
var data = GetDataFromBackend(propertyNamesFromDerived);
_data = data;
}
}
public class MyConcrete : MyBase
{
public MyConcrete(){
// Possibly use Reflection here
Hello = _data["Hello"];
ID = new Guid(data["ID"]);
}
public string Hello {get;set;}
public Guid ID {get; set;}
}
As you see, I want the constructor of my base class to know about the properties of the derived class I'm instantiating.
Now, this seems like a huge and big code smell, so let me give some more background about my intentions, maybe there is a better way.
I have a backend system that stores Key/Value Pairs, essentially a Dictionary<string,string>. I want to abstract away working with this backend system in a way where people can create classes whose properties are Keys into the backend system. When they construct this object, it will automatically load the data from that system and initialize all the variables to it.
In other words, I've just reinvented serialization, except that I don't control the backend system and just rather make working with it really painless. I don't want callers to have to call Initialize() after constructing the object, because in 100% of the cases you have to initalize it after constructing.
I don't want to move the initialize code into the Derived Classes, except for string-to-business-object conversion.
Would I have to use a Factory? Or is it considered safe to look at the property names of a derived class in a base constructor? (Don't care about their values and that they aren't initialized, just need the names).
Or is there a better way altogether to provide a facade between a Dictionary of strings and a concrete business object?
Edit: This is .net 3.5, so no System.Dynamic which would make this trivial :(
Edit 2: After looking at the Answers and thinking through this some more, I guess my question really boils down to this now: Is calling GetType().GetProperties() from a base constructor in order to get the Names of Properties and if they are decorated with a certain Attribute safe?
Wait, let's stop here for a second and do this properly. It shouldn't be MyBase's responsibility to do this.
So you write a class that manages getting stuff out of the backend for you, and you write a method on that class that is something like
T Get<T>() where T : new()
and you make Get responsible for reading the dictionary out of the backend and using reflection to populate an instance of T. Thus, you say
var concrete = foo.Get<MyConcrete>();
This isn't hard, and it's the right way to do it.
Incidentally, the code for Get is going to look something like
T t = new T();
var properties = typeof(T).GetProperties();
foreach(var property in properties) {
property.SetValue(t, dictionary[property.Name], null);
}
return t;
where dictionary is your loaded up key/value pairs. It turns out there are more optimal ways to do this, but unless it's a bottleneck I wouldn't worry about it.
The better way to do this would be to make the classes use the dictionary directly:
public string Hello {
get { return (string)base.data["Hello"]; }
set { base.data["Hello"] = value; }
}
You may want to call TryGetValue in the getter so that you can return a default value if the key isn't there. (You should probably do that in a separate method in the base class)
You can make a code snippet to make the properties easier to create.
If you don't want to do it this way, you can call GetType().GetProperties() to get PropertyInfo objects for the properties in your class, then call SetValue(this, value).
This will be slow; there are various tricks you can use to speed it up using expression trees, CreateDelegate, or IL generation.
Maybe try the Template method pattern
Have you considered using an ExpandoObject? With it you can dynamically add properties and inspect them (when serializing for example).
I'm not sure if it's what you really should do, but here's what you asked for (put this in Initialize, and you'll get a list of the derived property names):
var derivedProps = this.GetType().GetProperties();
var propNames = new List<string>(derivedProps.Select(x => x.Name));
From there, using the PropertyInfos in derivedProps, you can set the properties.
You can't really safely do anything to those properties in the base-class constructor anyway as some derived constructor may reset them anyway. You're much better off doing a two-phased load (e.g. call Initialize explicitly)
Following up on InternalsVisibleTo. I have looked at c# Instantiating Internal class with private constructor, and this has helped but I'm trying to cast the returned object as the internal type and, honestly I'm not 100% that that is possible.
I'm trying the route of Reflection to fix this issue, but I'm having a tough time trying to figure out how to instantiate an internal type with private methods using reflection. I can go as far as pulling the type and getting the constructor and creating an object.
How would I preform the cast of the object if the type I wish to cast is an internal type.?
public object InitPrivateCoreObjects(string Type)
{
Assembly Core = Assembly.Load("Stuff.Core, Version=0.3.3881.21340, Culture=neutral, PublicKeyToken=4fe470e63e2d354e");
Type TypeToReflect = Core.GetType("Stuff.Core.AssemblyWithIdentifer");
object o = Activator.CreateInstance(TypeToReflect);
MethodInfo mi = TypeToReflect.GetMethod("AssemblyWithIdentifer");
object newObject = mi.Invoke(o,null);
//alternatively
//ConstructorInfo ctor = TypeToReflect.GetConstructor(new Type[]{TypeToReflect.GetType()});
//ctor.Invoke(newObject, null);
return newObject;
}
I can get the type of the internal class,
I can call the constructor and instantiate an object of the type. However, since I don’t have any access to the internal type I can’t cast it and manipulate it from there.
I understand I can use Reflection.Emit to create a new class based on that type, but if I'm going that route then I might as well just copy the entire contents of the project I'm trying to access into my test project. This would be really wastefully and pointless and would require me to throw in stuff from other projects and creating a mess and it's absolutely not the route I want to go at this time.
I've seen examples accessing individual methods and properties but none that instantiate an entire class. I'm not 100% sure it's possible since in the order of operations reflection happens before access modifiers are looked at.
Can this be done, and if so, how?
For clairification sake I wanted to use the instantiated object for testing purposes and [Assembly:InternalsVisibleTo("")] wasn't working due to bug which I'm currently working around. See here for original question.
Given that you only know the type at execution time, there's really no such concept as "returning the object as the internal type". Think about what you'd want the method signature to look like... there's no way you could express it.
If the calling code knows about it in a strongly typed way, you should make the code generic instead:
public T InitPrivateCoreObjects<T>()
{
Type type = typeof(T);
...
return (T) newObject;
}
... but if the calling code doesn't know about it, that's not helpful to it.
If you could explain more about why you think you want this ability, we could try to suggest alteratives.
I can use Reflection.Emit to create a new class based on that type
Not really: code generated using Reflection.Emit follows the same rules as your own C#. You can't use it to bypass internal protection.
I've seen examples accessing individual methods and properties
That's what you'll need to do: use reflection to look up and invoke individual methods and properties.
A couple of alternatives:
Modify the internal class to implement some interface, and make that interface public. Call methods on the interface as normal.
Get [InternalsVisibleTo] working. This is the right way to go.
This is not really a direct answer to your question, but you may find this useful:
ExposedObject
If you don't have access to the internal type, nor does that type implement any public interface that you consider sufficient to interact with it, but you know beforehand the names and signatures of members on that type, this is probably your best choice.
Ok so I'm currently working with a set of classes that I don't have control over in some pretty generic functions using these objects. Instead of writing literally tens of functions that essentially do the same thing for each class I decided to use a generic function instead.
Now the classes I'm dealing with are a little weird in that the derived classes share many of the same properties but the base class that they are derived from doesn't. One such property example is .Parent which exists on a huge number of derived classes but not on the base class and it is this property that I need to use.
For ease of understanding I've created a small example as follows:
class StandardBaseClass {} // These are simulating the SMO objects
class StandardDerivedClass : StandardBaseClass {
public object Parent { get; set; }
}
static class Extensions
{
public static object GetParent(this StandardDerivedClass sdc) {
return sdc.Parent;
}
public static object GetParent(this StandardBaseClass sbc)
{
throw new NotImplementedException("StandardBaseClass does not contain a property Parent");
}
// This is the Generic function I'm trying to write and need the Parent property.
public static void DoSomething<T>(T foo) where T : StandardBaseClass
{
object Parent = ((T)foo).GetParent();
}
}
In the above example calling DoSomething() will throw the NotImplemented Exception in the base class's implementation of GetParent(), even though I'm forcing the cast to T which is a StandardDerivedClass.
This is contrary to other casting behaviour where by downcasting will force the use of the base class's implementation.
I see this behaviour as a bug. Has anyone else out there encountered this?
I see this behaviour as a bug.
This behavior is correct. Since your method DoSomething is constraining T to StandardBaseClass, you only have access to the specific methods of StandardBaseClass, not any methods or properties of a derived class. Since StandardBaseClass does not have a Parent property, this is invalid, and should be invalid, by design.
There are two potential options here - You can use reflection to pull out the Parent property, or use C# 4's dynamic type, and treat this as a dynamic object. Both bypass the standard type checking in the compiler, however, so will require you to do extra type checking at runtime to verify that the Parent property exists.
Create an interface that contains the Parent property. Have each class that has a Parent property implement that interace. You will then be able to create a generic method that accepts a parameter of type IHaveParent, and it will do the right thing.
For anyone that is interested an succinct answer to this situation is answered by Stephen Cleary on msdn here:
http://social.msdn.microsoft.com/Forums/en-AU/csharpgeneral/thread/95833bb3-fbe1-4ec9-8b04-3e05165e20f8?prof=required
To me this is a divergence in the class hierarchy. By this this I mean that either the base class has parent, or the derived classes with Parent are derived from an abstract child of the base.
Lol as John says, an interface as opposed to an abstract class is sufficient too.
You idea won't work because the compiler can never guarantee that the base class actually would have such a property. And it won't just select the "right" one based on if it has it or not.
The only way you can do this is using reflection and then test at runtime if the requested property exists on the inspected class. You have to judge yourself if that is a viable way to do for your project (reflection is slow and requires maximum rights).
This is correct, as the compiler only knows that it can bind to your type as a StandardBaseClass. The binding is not done at runtime (where it could potentially decide to use the StandardDerivedClass overload.
If you know that it's a StandardDerivedClass, then why not just cast it as such?
object Parent = ((StandardDerivedClass)foo).Parent;
It's a bit ugly, but you can accomplish this using a Registration system, where you register delegates for different possible derived classes that expose the 'shared' property/method and then use something like a Dictionary<Type,Func<SomeT>> to store the delegates. If you know all of the derived types ahead of time and don't have to load plug-ins or the like, you can also use the classic ugly if/else-if structure. Either way you're basically creating your own substitute for what should have been supported by the virtual method table.
I'm writing a wrapper for the WinForms ComboBox control that will let me populate the dropdown with a List<T>, and has a Selected property that returns an item of type T (or null if nothing selected).
Rather than having a Selected property, I'd like it to be named based on the generic type automatically. For example:
MyDropDownList<User> would have a SelectedUser property
MyDropDownList<Department> would have a SelectedDepartment property
MyDropDownList<State> would have a SelectedState property
With LINQ, I can create anonymous types during grouping, like so:
var usersByGender = users
.GroupBy(x => x.Gender)
.Select(group => new {Gender = group.Key, List = group.ToList()});
Which will result in a list of the generated anonymous type containing a Gender property and List<User> that are detectable by IntelliSense. The question is, can I somehow do this with properties in a generic class?
EDIT: I now realize I'm essentially asking for "method_missing" in C# 3.0, which is probably impossible. I'm open to suggestions, though.
I don't think you can do it. The only approach that has even a remote chance of working would be to create some kind of factory method that created the type and returned it. Basically your generic type becomes a base class and IL is dynamically written creating a concrete class that inherits from the generic but with the new property added in. Of course the object that is returned would be really anonymous and you'd only be able to access it through reflection since you wouldn't have a type to actually cast to:
public static class CrazyFactory
{
public static object CreateTypedComboList<T>()
{
//magic happens
return object;
}
}
Using it would then require
object userCombo = CrazyFactory.CreateTypedComboList<User>();
PropertyInfo selectedUserProperty = userCombo.GetType().GetProperty("SelectedUser");
selectedUserProperty.SetValue(userCombo, user);
Which is hardly a step up from a simple T SelectedItem property.
From a brief look it appears that this type of thing will be easier when c# 4.0 brings us dynamic types. By implementing the IDynamicObject interface it will be possible to catch all calls to undefined properties and handle them so you could use logic like the following:
public override MetaObject GetMember(GetMemberAction action, MetaObject[] args)
{
//not sure on the real property name here...
string actionName = action.Name;
if (actionName = "Selected" + typeof(T).Name)
{
return SelectedItem; //in some MetaObject wrapper
}
}
I've been following this article and haven't touched dynamics myself yet, but it certainly appears like what you want is possible. I still wouldn't do it though - you won't get Intellisense and it seems like a fragile and complicated method for defining functionality.
No, you cannot do that. The whole idea behind generic types is that they apply equally to all types which can be specified in the generic parameter. This wouldn't be the case if every specialization were allowed to declare differently-named members.