Getting value of static property by string name - c#

There's a great post here that gives a way to get the value of a property by its string name:
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
Currently, I'm trying to get the value of a static property in a base class. If I try to use BaseClass.Prop as 'src', however, I get a null reference exception. While src isn't associated with an explicit instance, the value of Prop I'm trying to get nevertheless still exists.
Is there a workaround for static properties?

Don't send a src when calling static properties.
Type t = src.GetType();
if (t.GetProperty(propName).GetGetMethod().IsStatic)
{
src = null;
}
return t.GetProperty(propName).GetValue(src, null);

To get a static property, you cannot pass an object reference. To detect if a property-get is static, look at propertyInfo.GetGetMethod().IsStatic. Here's your GetPropValue method:
public static object GetPropValue(object src, string propName)
{
var propertyInfo = src.GetType().GetProperty(propName);
if (propertyInfo.GetGetMethod().IsStatic)
return propertyInfo.GetValue(null, null);
else
return propertyInfo.GetValue(src, null);
}

Related

get field by name

I am trying to create a function that can return a field from its object.
Here is what I have so far.
public class Base
{
public string thing = "Thing";
public T GetAttribute<T>(string _name)
{
return (T)typeof(T).GetProperty(_name).GetValue(this, null);
}
}
What I would ideally like is to call:
string thingy = GetAttribute<string>("thing");
but I have a feeling I got the wrong end of the stick when reading up on this because I keep getting null reference exceptions.
First thing - thing is a field, not a property.
Another thing is that you have to change parameter type to get it working:
public class Base {
public string thing = "Thing";
public T GetAttribute<T> ( string _name ) {
return (T)typeof(Base).GetField( _name ).GetValue (this, null);
}
}
BTW - you can get property/field value by referencing an instance:
var instance = new Base();
var value = instance.thing;
thing is a field not a property. You should use GetField method instead of GetProperty.
Another problem is you are looking in typeof(T). You should look for the field in typeof(Base).
The whole function should be changed to
public T GetAttribute<T>(string _name)
{
return (T)GetType().GetField(_name).GetValue(this);
}
If you want to have an extension method to get field value of a type you can use this
public static class Ex
{
public static TFieldType GetFieldValue<TFieldType, TObjectType>(this TObjectType obj, string fieldName)
{
var fieldInfo = obj.GetType().GetField(fieldName,
BindingFlags.Instance | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic);
return (TFieldType)fieldInfo.GetValue(obj);
}
}
Use it like
var b = new Base();
Console.WriteLine(b.GetFieldValue<string, Base>("thing"));
Using BindingFlags will help you to get field value even if it is private or static field.

C# set property value of property passed to method via Func<T>

I use this method to get the value of a property in a method:
public static T Decrypt<T>(Func<T> prop, string username, string password)
{
T value = prop();
//do cool stuff with t
return value;
}
I'm looking for a way to do the other way arround, set the value of my property
public static void Encrypt<T>(Func<T> prop, T value, string username, string password)
{
//do stuff with value
??? set prop ???
}
I've searched and tried Expressions, but cloud not get it to work:
public static void Encrypt<T>(Expression<Func<T>> property, T value, string username, string password)
{
//do stuff with value
var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo;
propertyInfo.SetValue(property, value);
}
Youd could change the Encrypt function like this:
public static void Encrypt<T>(Action<T> prop, T value, string username, string password)
{
// awesome stuff before
prop(value);
// awesome stuff after
}
Then call Encrypt :
Encrypt(value => obj.Prop = value, 23, "", "");
You stack in misunderstanding of how SetValue method behave, it takes an real object as first parameter which have the property which propertyInfo is described, so you need to take that object form expression instead of using expression itself, please take a look at the following answer on stakoverflow which may help you
link to post
You can try this to set the property by name:
Type t = ctrl.GetType();
t.InvokeMember(propName, BindingFlags.Instance | BindingFlags.SetProperty |BindingFlags.Public, null, ctrl, new object[] { value });

How to get PropertyDescriptor for current property?

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)

Set objects properties from string in C#

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.

Easy Reflection question C#

I want to supply unknown "object" and return the value of one of its members. Response is required in C#.
Generically I guess I'm looking for the code to this method
public static object GetObjectMemberValue (object myObject, string memberName)
More specifically I'm doing this for resource strings in Silverlight and need to write this method. It resides in a common project is used against a few different Resx dictionaries, thus I don't have access to the type information.
public static string GetString (object StringResources, string ResourceId)
Thank you!
This will get your value... Can you give me more info in the resx part of the question?
public static object GetObjectMemberValue(object myObject, string memberName)
{
PropertyInfo dateProperty = myObject.GetType().GetProperty(memberName);
return dateProperty.GetValue(myObject, null);
}
if you know the objects type, then cast to it?
Or it should at least implement an interface if you don't know the explicit type?
MyType value = (MyType)objectGetter() //this is the function that returns the unknown.
value.GetMember()
static class ObjectExtensions {
public static object GetObjectPropertyValue(this object o, string propertyName) {
return o.GetType().GetProperty(propertyName).GetValue(o, null);
}
}
class Test {
public string Message {get; set;}
}
class Program {
static void Main(string[] args) {
object t = new Test { Message = "Hello, World!" };
Console.WriteLine(t.GetObjectPropertyValue("Message").ToString());
}
}
First get the type of the object:
Type myObjectType = myObject.GetType();
Then, you can use the returned Type object to get the property's info, and then it's value.
o.GetType().InvokeMember( "MemberName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty, null, o, null );

Categories

Resources