Is there any way to set the properties of the objects from string. For example I have "FullRowSelect=true" and "HoverSelection=true" statements as string for ListView property.
How to assign these property along with their values without using if-else or switch-case statments? Is there any SetProperty(propertyName,Value) method or similar for this?
Try this:
private void setProperty(object containingObject, string propertyName, object newValue)
{
containingObject.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, containingObject, new object[] { newValue });
}
You can use reflection to do this:
myObj.GetType().GetProperty("FullRowSelect").SetValue(myObj, true, null);
You can do this with reflection, have a look at the PropertyInfo class's SetValue method
YourClass theObject = this;
PropertyInfo piInstance = typeof(YourClass).GetProperty("PropertyName");
piInstance.SetValue(theObject, "Value", null);
Try this:
PropertyInfo pinfo = this.myListView.GetType().GetProperty("FullRowSelect");
if (pinfo != null)
pinfo.SetValue(this.myListView, true, null);
First variant is to use reflection:
public class PropertyWrapper<T>
{
private Dictionary<string, MethodBase> _getters = new Dictionary<string, MethodBase>();
public PropertyWrapper()
{
foreach (var item in typeof(T).GetProperties())
{
if (!item.CanRead)
continue;
_getters.Add(item.Name, item.GetGetMethod());
}
}
public string GetValue(T instance, string name)
{
MethodBase getter;
if (_getters.TryGetValue(name, out getter))
return getter.Invoke(instance, null).ToString();
return string.Empty;
}
}
to get a property value:
var wrapper = new PropertyWrapper<MyObject>(); //keep it as a member variable in your form
var myObject = new MyObject{LastName = "Arne");
var value = wrapper.GetValue(myObject, "LastName");
You can also use Expression class to access properties.
There isn't such a method, but you could write one using reflection.
You can look at Reflection. Its possible to find property and set its value thanks to this. But you need to parse your string yourself. And it may be problem geting valid value of correct type from string.
This can be accomplished with reflection, for example look at this question.
Related
I have a requirement to extract all public read-write properties that are not enumerable, unless they are a string. This is currently done by refelction and wondering if this can be done with FastMember.
I tried something like the code below but it doesn't do what I want. Can I do this with the current version of FastMember?
Cheers,
Berryl
protected void LoadCache(IHaveEditableStateProperties originator) {
var type = originator.GetType();
_accessor = TypeAccessor.Create(type);
var members = _accessor.GetMembers();
_editableState = new Dictionary<string, object>();
foreach (var member in members) {
if(member.Type == typeof(PropertyInfo)) {
_editableState.Add(member.Name, _accessor[originator, member.Name]);
}
}
}
...
}
As I understand it, member.Type as returned from FastMember is the return type of the property or method. It should never be PropertyInfo as you are checking for in your code. _accessor[originator, member.Name] should return the current value of the property.
I have a class with custom enum:
public enum Capabilities{
PowerSave= 1,
PnP =2,
Shared=3, }
My class
public class Device
{
....
public Capabilities[] DeviceCapabilities
{
get { // logic goes here}
}
Is there a way using reflection to get the value of this field during runtime?
I tried the following but got null reference exception
PropertyInfo[] prs = srcObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo property in prs)
{
if (property.PropertyType.IsArray)
{
Array a = (Array)property.GetValue(srcObj, null);
}
}
EDIT: Thanks for your answers, what I really need is a way to get the values dynamically without the need to specify the enum type.
Something like:
string enumType = "enumtype"
var property = typeof(Device).GetProperty(enumType);
Is that possible?
The following should do what you desire.
var property = typeof(Device).GetProperty("DeviceCapabilities");
var deviceCapabilities = (Capabilities[])property.GetValue(device);
Note that the method Object PropertyInfo.GetValue(Object) is new in .NET 4.5. In previous versions you have to add an additional argument for the indices.
var deviceCapabilities = (Capabilities[])property.GetValue(device, null);
This should work:
var source = new Device();
var property = source.GetType().GetProperty("DeviceCapabilities");
var caps = (Array)property.GetValue(source, null);
foreach (var cap in caps)
Console.WriteLine(cap);
If you want to enumerate all the possible values of an Enum and return as an array then try this helper function:
public class EnumHelper {
public static IEnumerable<T> GetValues<T>()
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
}
Then you can simply call:
Capabilities[] array = EnumHelper.GetValues<Capabilities>();
If that isn't what you are after then I'm not sure what you mean.
You can try this
foreach (PropertyInfo property in prs)
{
string[] enumValues = Enum.GetNames(property.PropertyType);
}
Hope it helps.
I want to get value for a dynamic property of a dynamic object.
Here is my Code..
public string ReturnProperty(object ob, string prop)
{
Type type = ob.GetType();
PropertyInfo pr = type.GetProperty(prop);
//Here pr is null..Dont know whats wrong
return pr.GetValue(ob, null).ToString();
}
My guess is that either it isn't a public property, or you've got the name wrong, or it isn't a property at all (but a public field).
It's impossible to say more without knowing what the actual type is, but that should be a start.
You mention that this is a "dynamic object" but that's not really very descriptive. Bear in mind that the CLR itself doesn't know anything about the DLR - if you mean this is a type which implements IDynamicMetaObjectProvider or extends DynamicObject, then you won't be able to get at the properties with "normal" reflection like this.
In my case ob did not have pr getter setter properly.
//causes GetProperty to return null
public class MyClass{
public object pr;
}
//Works
public class MyClass{
public object pr { get; set; }
}
In my case, I had to define get and set. See post above
public string MyPropertyName { get; set; }
After this I could get the property by:
typeof(MyClassItem).GetProperty("PropertyName")
If the item you are attempting to access doesn't have getter and setter accessors, then most likely it is a field.
So your code would work as follows:
FieldInfo fieldInfo = type.GetField(fieldName);
Try the Type.GetProperty(String, BindingFlags) overload and select the right binding flags.
Example for ExpandoObject(it implements IDynamicMetaObjectProvider Jon Skeet mentioned):
public static string ReturnProperty(object ob, string prop)
{
if (ob is ExpandoObject)
{
return ((ExpandoObject)ob).Single(e => e.Key == prop).Value.ToString();
}
Type type = ob.GetType();
PropertyInfo pr = type.GetProperty(prop);
return pr.GetValue(ob, null).ToString();
}
//--
dynamic dyna = new ExpandoObject();
dyna.Name = "Element";
Console.WriteLine(ReturnProperty(dyna, "Name"));
I had the same error, the problem lies in the field names, if you have a field to read from the sql "isField" and its class has a field is named "IsField". The compiler will read case sensitive , for all reason it's a different field, for that reason you have null. Check yours casesensitive fields nomenculature.
I was trying to access a public property, but I was using BindingFlags.NonPublic instead of BindingFlags.Public.
I tried this & it worked.
public string ReturnProperty(object ob, string prop)
{
Type type = ob.GetType();
PropertyInfo pr = type.GetProperty(prop);
//Here pr is null..Dont know whats wrong
return pr.GetValue(ob, null).ToString();
}
ReturnProperty(new { abc = 10 }, "abc");
Whats wrong???
I just came across this issue when I was passing in the wrong data of a sorted grid view in an MVC project.
public HolidaysGridViewModel()
{
this.Sort = "HolidayDate"; // this was the wrong name
this.SortDir = "ASC";
}
It made me realize after reading your question that you were most likely passing in the name of a business from the database instead of the name of the database column object and therefore no were results were found which may have been the cause of your null value.
i've some classes and want to access their properties using index or something like
ClassObject[0] or better will be ClassObject["PropName"]
instead of this
ClassObj.PropName.
Thanks
You need indexers:
http://msdn.microsoft.com/en-us/library/aa288465(v=vs.71).aspx
public class MyClass
{
private Dictionary<string, object> _innerDictionary = new Dictionary<string, object>();
public object this[string key]
{
get { return _innerDictionary[key]; }
set { _innerDictionary[key] = value; }
}
}
// Usage
MyClass c = new MyClass();
c["Something"] = new object();
This is notepad coding, so take it with a pinch of salt, however the indexer syntax is correct.
If you want to use this so you can dynamically access properties, then your indexer could use Reflection to take the key name as a property name.
Alternatively, look into dynamic objects, specifically the ExpandoObject, which can be cast to an IDictionary in order to access members based on literal string names.
You can do something like this, a pseudocode:
public class MyClass
{
public object this[string PropertyName]
{
get
{
Type myType = typeof(MyClass);
System.Reflection.PropertyInfo pi = myType.GetProperty(PropertyName);
return pi.GetValue(this, null); //not indexed property!
}
set
{
Type myType = typeof(MyClass);
System.Reflection.PropertyInfo pi = myType.GetProperty(PropertyName);
pi.SetValue(this, value, null); //not indexed property!
}
}
}
and after use it like
MyClass cl = new MyClass();
cl["MyClassProperty"] = "cool";
Note that this is not complete solution, as you need to "play" with BindingFlags during reflection access if you want to have non public properties/fields, static ones and so on.
public string this[int index]
{
get
{ ... }
set
{ ... }
}
This will give you an indexed property. You can set any parameter you wish.
I'm not sure what you mean here, but I'll say that you have to make ClassObject some sort of IEnumirable type, like List<> or Dictionary<> to use it the way to aim for here.
How can I get the PropertyDescriptor for the current property? For example:
[MyAttribute("SomeText")]
public string MyProperty
{
get{....}
set
{
// here I want to get PropertyDescriptor for this property.
}
}
You could try this:
public string Test
{
get
{
//Get properties for this
System.ComponentModel.PropertyDescriptorCollection pdc = System.ComponentModel.TypeDescriptor.GetProperties( this );
//Get property descriptor for current property
System.ComponentModel.PropertyDescriptor pd = pdc[ System.Reflection.MethodBase.GetCurrentMethod().Name ];
}
}
Here's a re-usable conversion function for those who got to this post looking for a general function:
public static PropertyDescriptor GetPropertyDescriptor(PropertyInfo PropertyInfo)
{
return TypeDescriptor.GetProperties(PropertyInfo.DeclaringType).Item(PropertyInfo.Name);
}
and here's an extension method:
public static PropertyDescriptor PropertyDescriptor(this PropertyInfo propertyInfo)
{
return TypeDescriptor.GetProperties(propertyInfo.DeclaringType)[propertyInfo.Name];
}
I found that the following worked:
// get property descriptions
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties ( this );
// get specific descriptor
PropertyDescriptor property = properties.Find ( PropertyName, false );
where PropertyName is a value passed into a method.
How about this?
this.GetType().GetProperty("MyProperty")
I think you're asking if you can do this without the string - i.e. some other token that represents 'this property'. I don't think that exists. But since you are writing this code anyway (?) what is the difficulty in just putting the name of the property in the code?
For future reference, you can now do this:
public static PropertyDescriptor? GetPropertyDescriptor(
this object target,
[CallerMemberName] string propertyName = ""
) => TypeDescriptor.GetProperties(target.GetType())
.Find(propertyName, ignoreCase: false)