How can I get a value from an unknown enum in C#? - c#

I'm actually programming a deepToString-Method that extends object. This uses reflection to get each property of an object and calls the deepToString-Method for this property. Everything works fine except of Enums. If I try to use PropertyInfo.GetValue() with an enum, it allways returns zero.
How can I get the real int-Value? What am I missing?

foreach (PropertyInfo propertyInfo in your_class.GetType().GetProperties())
{
if ((info.PropertyType.IsEnum) && (info.PropertyType.IsPublic))
{
foreach (FieldInfo fInfo in this.propertyInfo.PropertyType.GetFields(BindingFlags.Public | BindingFlags.Static))
{
ListItem item = new ListItem(fInfo.Name, fInfo.GetRawConstantValue().ToString());
//... use it
}
}
}
I have to add that reflection is EVIL. Rare are the occasions where it is really needed..

public enum Foo
{
Boo,
Koo
}
public Foo foo { get; set; }
[Fact]
public void FactMethodName()
{
foo = Foo.Koo;
var propertyInfo = this.GetType().GetProperty("foo");
if (propertyInfo.PropertyType.IsEnum)
{
var value = propertyInfo.GetValue(this, null);
Console.Out.WriteLine("value = {0}", value); //prints Koo
int asInt = (int)value;
Console.Out.WriteLine("asInt = {0}", asInt); //prints 1
}
}

Related

Get members of custom class to read their values

Let say I have class:
public class TestClass
{
public string Prop1 { get; set; }
public int Field1 = 1234567890;
public string Method1() { return "ABCDEFGHIJKLMNOPQRSTUVXYZ"; }
}
... class instance and list:
TestClass TC = new TestClass();
List<object> TCValues = new List<object>();
... and populate the list with values in loop:
foreach (var v in TC.GetType().GetProperties()) // or .GetFields()
{
TCValues.Add(v.GetValue(TC, null));
}
... problem is that in my particular case I need to get list of all class members first, then filter them to properties and fields (ignoring methods of course) and then read their values as I did in first example:
foreach (var v in TC.GetType().GetMembers())
{
if (v.MemberType == System.Reflection.MemberTypes.Property || v.MemberType == System.Reflection.MemberTypes.Field)
{
TCValues.Add(v.?????????); // Can't get values !
}
}
... I understand that GetMembers() returns class MemberInfo which unlike PropertyInfo and FieldInfo doesn't contain method GetValue(). Is there any way to read values from filtered property and field members inside the loop iterating through MemberInfo collection ?
In your foreach-Loop try
foreach (var v in TC.GetType().GetMembers())
{
if (v is PropertyInfo)
{
var value = ((PropertyInfo)v).GetValue(TC, null);
TCValues.Add(value);
}
else if (v is FieldInfo)
{
var value = ((FieldInfo) v).GetValue(TC);
TCValues.Add(value);
}
}
TC.GetType().GetProperty(propName).GetValue(TC);
You have to cast the members to the correct type:
foreach (var v in TC.GetType().GetMembers())
{
if (v.MemberType == System.Reflection.MemberTypes.Property)
{
TCValues.Add(((System.Reflection.PropertyInfo)v).GetValue(TC,null));
}
else if (v.MemberType == System.Reflection.MemberTypes.Field)
{
TCValues.Add(((System.Reflection.FieldInfo)v).GetValue(TC));
}
}

Get property of generic class

I have a generic class, and an object value where obj.GetType().GetGenericTypeDefinition() == typeof(Foo<>).
class Foo<T>
{
public List<T> Items { get; set; }
}
How do I get the value of Items from obj? Remember, obj is an Object, I can't cast obj as Foo because I don't know what T is.
I was hoping to use reflection for this, but each time I do GetProperty("Items") it returns null. However, if someone knows a good way to do this without reflection, by all means.
Let's say my code looks like this:
//just to demonstrate where this comes from
Foo<int> fooObject = new Foo<int>();
fooObject.Items = someList;
object obj = (object)fooObject;
//now trying to get the Item value back from obj
//assume I have no idea what <T> is
PropertyInfo propInfo = obj.GetType().GetProperty("Items"); //this returns null
object itemValue = propInfo.GetValue(obj, null); //and this breaks because it's null
You should be able to use:
Type t = obj.GetType();
PropertyInfo prop = t.GetProperty("Items");
object list = prop.GetValue(obj);
You will not be able to cast as a List<T> directly, of course, as you don't know the type T, but you should still be able to get the value of Items.
Edit:
The following is a complete example, to demonstrate this working:
// Define other methods and classes here
class Foo<T>
{
public List<T> Items { get; set; }
}
class Program
{
void Main()
{
//just to demonstrate where this comes from
Foo<int> fooObject = new Foo<int>();
fooObject.Items = new List<int> { 1, 2, 3};
object obj = (object)fooObject;
//now trying to get the Item value back from obj
//assume I have no idea what <T> is
PropertyInfo propInfo = obj.GetType().GetProperty("Items"); //this returns null
object itemValue = propInfo.GetValue(obj, null);
Console.WriteLine(itemValue);
// Does not print out NULL - prints out System.Collections.Generic.List`1[System.Int32]
IList values = (IList)itemValue;
foreach(var val in values)
Console.WriteLine(val); // Writes out values appropriately
}
}
#ReedCopsey is absolutely correct, but in case you're really asking the question "How do I fish out the generic details of a type?", here's some "Fun with Reflection":
public void WhatsaFoo(object obj)
{
var genericType = obj.GetType().GetGenericTypeDefinition();
if(genericType == typeof(Foo<>))
{
// Figure out what generic args were used to make this thing
var genArgs = obj.GetType().GetGenericArguments();
// fetch the actual typed variant of Foo
var typedVariant = genericType.MakeGenericType(genArgs);
// alternatively, we can say what the type of T is...
var typeofT = obj.GetType().GetGenericArguments().First();
// or fetch the list...
var itemsOf = typedVariant.GetProperty("Items").GetValue(obj, null);
}
}
Something like this should do the trick:
var foo = new Foo<int>();
foo.Items = new List<int>(new int[]{1,2,3});
// this check is probably not needed, but safety first :)
if (foo.GetType().GetProperties().Any(p => p.Name == "Items"))
{
var items = foo.GetType().GetProperty("Items").GetValue(foo, null);
}
You have to use System.Reflection namespace to execute the program successfully.
This program gives you Property Name and Value of any Generic Class
You can check this code fiddle on C# Online Rexter Tool Compiler at
using System;
using System.Reflection;
namespace GenericPropertyExample
{
//Declaring a Sample Class
public class class1
{
public string prop1 { get; set; }
public string prop2 { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
//Creating Class Object
class1 objClass1 = new class1 { prop1 = "value1", prop2 = "value2" };
//Passing Class Object to GenericPropertyFinder Class
GenericPropertyFinder<class1> objGenericPropertyFinder = new GenericPropertyFinder<class1>();
objGenericPropertyFinder.PrintTModelPropertyAndValue(objClass1);
Console.ReadLine();
}
//Declaring a Generic Handler Class which will actually give Property Name,Value for any given class.
public class GenericPropertyFinder<TModel> where TModel : class
{
public void PrintTModelPropertyAndValue(TModel tmodelObj)
{
//Getting Type of Generic Class Model
Type tModelType = tmodelObj.GetType();
//We will be defining a PropertyInfo Object which contains details about the class property
PropertyInfo[] arrayPropertyInfos = tModelType.GetProperties();
//Now we will loop in all properties one by one to get value
foreach (PropertyInfo property in arrayPropertyInfos)
{
Console.WriteLine("Name of Property is\t:\t" + property.Name);
Console.WriteLine("Value of Property is\t:\t" + property.GetValue(tmodelObj).ToString());
Console.WriteLine(Environment.NewLine);
}
}
}
}
}
Hey guys ive been struggeling with the same issue with generic typs and finally found the solution that gets the value
--------Small code snippet of the method that does the trick ------------------
public void printFields()
{
// Is the list empty
if (this.list_.Count == 0)
{
//Y => Forced exit no object info
return;
}
try
{
// Get first item from list
T item = this.list_[0];
// Get the type of object
//**Type thisType = item.GetType();
// Get array of all fields
FieldInfo[] thisFieldInfo = item.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
// Loop through all fields and show its info
for (int ix = 0; ix < thisFieldInfo.Length; ix++)
{
// Get Field value
String strVal = thisFieldInfo[ix].GetValue(item).ToString();
// Display item
Console.WriteLine("'{0}' is a {1} and has value {2}", thisFieldInfo[ix].Name, thisFieldInfo[ix].FieldType, strVal);
}
}
catch (SecurityException e)
{
Console.WriteLine("Exception: " + e.Message);
}
}

Loop through constant members of a class

I have a class with constant strings in it. I'd like to throw all of those strings into a drop down collection. What is the best way to do this? This is what I have now and in theory, I would think that it would be the best way to do this.
public class TestClass
{
private const string _testA = "Test A";
private const string _testB = "Test B";
public string TestA
{
get { return _testA; }
}
public string TestB
{
get { return _testB; }
}
}
public DropDownItemCollection TestCollection
{
DropDownItemCollection collection = new DropDownItemCollection();
TestClass class = new TestClass();
foreach (string testString in class)
{
DropDownItem item = new DropDownItem();
item.Description = testString;
item.Value = testString;
collection.Add(item);
}
return collection;
}
The problem is that this returns an error on the foreach: "...does not contain a public definition for GetEnumerator." I've tried to create a GetEnumerator but I've been unsuccessful and I haven't worked with GetEnumerator in the past.
Any help is greatly appreciated!
A little late but wouldn't this be a better solution?
http://weblogs.asp.net/whaggard/archive/2003/02/20/2708.aspx
private FieldInfo[] GetConstants(System.Type type)
{
ArrayList constants = new ArrayList();
FieldInfo[] fieldInfos = type.GetFields(
// Gets all public and static fields
BindingFlags.Public | BindingFlags.Static |
// This tells it to get the fields from all base types as well
BindingFlags.FlattenHierarchy);
// Go through the list and only pick out the constants
foreach(FieldInfo fi in fieldInfos)
// IsLiteral determines if its value is written at
// compile time and not changeable
// IsInitOnly determine if the field can be set
// in the body of the constructor
// for C# a field which is readonly keyword would have both true
// but a const field would have only IsLiteral equal to true
if(fi.IsLiteral && !fi.IsInitOnly)
constants.Add(fi);
// Return an array of FieldInfos
return (FieldInfo[])constants.ToArray(typeof(FieldInfo));
}
If you need the names you can do
fi.GetValue(null)
inside the loop.
I just had the same challenge; to get all constants of my class (not properties!). Based on the most popular answer (for properties) and John's answer (for constants) I wrote this. I tested it and it works well.
private List<string> lstOfConstants= new List<string>();
foreach (var constant in typeof(TestClass).GetFields())
{
if (constant.IsLiteral && !constant.IsInitOnly)
{
lstOfConstants.Add((string)constant.GetValue(null));
}
}
You could implement a method that yields the strings:
public Ienumerable<string> GetStrings(){
yield return TestA;
yield return TestB;
}
Else you should look into reflection to return the properties that are static and string and then get the values by calling them.
Regards GJ
You could use reflection to loop through all the properties:
public DropDownItemCollection TestCollection
{
var collection = new DropDownItemCollection();
var instance = new TestClass();
foreach (var prop in typeof(TestClass).GetProperties())
{
if (prop.CanRead)
{
var value = prop.GetValue(instance, null) as string;
var item = new DropDownItem();
item.Description = value;
item.Value = value;
collection.Add(item);
}
}
return collection;
}
You can use reflection to loop trought the class properties:
var instance = new TestClass();
foreach(PropertyInfo pi in typeof(TestClass))
{
var val = pi.GetValue(instance,null);
}
You need to use reflection to get name of each String from your custom type, and then also/optionally get the value of each one of those Strings...
Something like this:
TestClass theClass = new TestClass();
foreach (PropertyInfo property in theClass.GetType().GetProperties())
{
Console.WriteLine(property.Name);
Console.WriteLine(property.GetValue(theClass, null));
}

How to convert variable name to string in c#.net? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding the Variable Name passed to a Function in C#
public new Dictionary<string, string> Attributes { get; set; }
public string StringAttributes = string.Empty;
public int? MaxLength { get; set; }
public int? Size { get; set; }
public int? Width { get; set; }
public int? Height { get; set; }
protected override void OnInit(EventArgs e) {
Attributes = new Dictionary<string, string>();
Attributes.Add("MaxLength", MaxLength.ToString());
Attributes.Add("Size", Size.ToString());
Attributes.Add("Width", Width.ToString());
Attributes.Add("Height", Height.ToString());
base.OnInit(e);
}
protected override void OnPreRender(EventArgs e) {
if (Attributes != null) {
StringBuilder attributes = new StringBuilder();
foreach (var item in Attributes) {
if (!string.IsNullOrWhiteSpace(item.Value)) {
attributes.Append(item.Key + "=\"" + item.Value + "\" ");
}
}
StringAttributes = attributes.ToString();
}
}
The problem here is, instead of using Attributes.Add("MaxLength", MaxLength.ToString()); and repeat the same process for other properties, could we not just make a function that is also able to add values to the dictionary, where the keys to be added are their variable names?
Say,
public void addAttribute(object variable){
Attributes = new Dictionary<string, string>();
Attributes.Add(variable.Name, variable.Value);
}...
I guess this is also possible to do with reflection, getting all the nullable properties and looping through them then adding each to the dictionary... But for as long as there are any other ways, we would not stick to reflection.
But if reflection is the only choice, then another problem now would be how to get the nullable properties of the class...
Any help would be greatly appreciated. Thank you.
I can't think of way to do it without reflection.
In order to get all the nullable properties you can you similar code to this:
GetType().GetProperties()
.Where(property =>
property.PropertyType.IsGenericType &&
property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
Usage example that fills attributes dictionary:
PropertyInfo[] typeProperties = GetType().GetProperties();
var nullableProperties = typeProperties.Where(property =>
property.PropertyType.IsGenericType &&
property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>));
var attributes = new Dictionary<string, string>();
foreach (var nullableProperty in nullableProperties)
{
object value = nullableProperty.GetValue(this,null);
attributes.Add(nullableProperty.Name, value == null ?
string.Empty : value.ToString());
}
I'm not sure I fully understand your question without more context, but perhaps this is helpful
If the concern is over reflection overhead for multiple invocations:
Cache that information.
try EmitMapper to fill in values
try AutoMapper to fill in the values
If the problem is getting a variable name via strongly typed compilation then you can use
The Member class I saw on a post from Oliver Hhanappi. Examples of its use are here on my blog
Below is my complete solution. I would say your best bet is to use reflection, as what you're asking is sort of a meta-task. As far as how do you know which properties to add, I would suggest defining your own attribute and applying it to the fields/properties that you want to inspect.
Usage:
Dictionary<string, string> attributes = Inspector<MyClass>.Inspect(target);
The reflection in my sample code is executed once per type inspected, as it is executed within the static constructor of my generic Inspect class:
// apply this attribute to any properties or fields that you want added to the attributes dictionary
[AttributeUsage(
AttributeTargets.Property |
AttributeTargets.Field |
AttributeTargets.Class |
AttributeTargets.Struct |
AttributeTargets.Interface,
AllowMultiple = true, Inherited = true)]
public class InspectAttribute : Attribute
{
// optionally specify the member name explicitly, for use on classes, structs, and interfaces
public string MemberName { get; set; }
public InspectAttribute() { }
public InspectAttribute(string memberName)
{
this.MemberName = memberName;
}
}
public class Inspector<T>
{
// Inspector is a generic class, therefore there will be a separate instance of the _InspectActions variable per type
private static List<Action<Dictionary<string, string>, T>> _InspectActions;
static Inspector()
{
_InspectActions = new List<Action<Dictionary<string, string>, T>>();
foreach (MemberInfo m in GetInspectableMembers(typeof(T)))
{
switch (m.MemberType)
{
case MemberTypes.Property:
{
// declare a separate variable for variable scope with anonymous delegate
PropertyInfo member = m as PropertyInfo;
// create an action delegate to add an entry to the attributes dictionary using the property name and value
_InspectActions.Add(
delegate(Dictionary<string, string> attributes, T item)
{
object value = member.GetValue(item, null);
attributes.Add(member.Name, (value == null) ? "[null]" : value.ToString());
});
}
break;
case MemberTypes.Field:
{
// declare a separate variable for variable scope with anonymous delegate
FieldInfo member = m as FieldInfo;
// need to create a separate variable so that delegates do not share the same variable
// create an action delegate to add an entry to the attributes dictionary using the field name and value
_InspectActions.Add(
delegate(Dictionary<string, string> attributes, T item)
{
object value = member.GetValue(item);
attributes.Add(member.Name, (value == null) ? "[null]" : value.ToString());
});
}
break;
default:
// for all other member types, do nothing
break;
}
}
}
private static IEnumerable<MemberInfo> GetInspectableMembers(Type t)
{
// get all instance fields and properties
foreach (MemberInfo member in t.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.GetField | BindingFlags.GetProperty))
{
// check if the current member is decorated with an Inspect attribute
object[] inspectAttributes = member.GetCustomAttributes(typeof(InspectAttribute), true);
if (inspectAttributes != null && inspectAttributes.Length > 0)
{
yield return member;
}
}
// now look for any Inspect attributes defined at the type level
InspectAttribute[] typeLevelInspectAttributes = (InspectAttribute[])t.GetCustomAttributes(typeof(InspectAttribute), true);
if (typeLevelInspectAttributes != null && typeLevelInspectAttributes.Length > 0)
{
foreach (InspectAttribute attribute in typeLevelInspectAttributes)
{
// search for members matching the name provided by the Inspect attribute
MemberInfo[] members = t.GetMember(attribute.MemberName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.FlattenHierarchy);
if (members != null && members.Length > 0)
{
foreach (MemberInfo member in members)
{
yield return member;
}
}
}
}
}
public static Dictionary<string, string> Inspect(T item)
{
// create a new attributes dictionary
Dictionary<string, string> attributes = new Dictionary<string, string>();
foreach (Action<Dictionary<string, string>, T> inspectAction in _InspectActions)
{
// execute each "inspect" action.
// This will execute the delegates we created earlier, causing entries to be added to the dictionary
inspectAction(attributes, item);
}
return attributes;
}
}
public class BasePage
{
public int? SomeValue { get; set; }
}
// example class with properties decorated with the Inspect attribute
[Inspect("SomeValue")] // also inspect the "SomeValue" property from the BasePage class
public class MyPage : BasePage
{
[Inspect]
public int? MaxLength { get; set; }
[Inspect]
public int? Size { get; set; }
[Inspect]
public int? Width { get; set; }
[Inspect]
public int? Height { get; set; }
public string GenerateAttributeString()
{
System.Text.StringBuilder attributes = new System.Text.StringBuilder();
foreach (KeyValuePair<string, string> item in Inspector<MyPage>.Inspect(this))
{
attributes.Append(item.Key + "=\"" + item.Value + "\" ");
}
return attributes.ToString();
}
}
You can use the following function to extract out the public Nullable properties from a class into the format your looking for. It also calls the getter method for the value.
This is using the same reflection use that #Elisha talked about. Also it does a .ToString() call to the value returned by the getter.
IDictionary<string, string> GetProps<T>(T DataObject)
{
if(null == DataObject)
return new Dictionary<string, string>();
var nullableProperties =
from property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
from accessor in property.GetAccessors(false)
let returnType = accessor.ReturnType
where returnType.IsGenericType
&& returnType.GetGenericTypeDefinition() == typeof(Nullable<>)
&& accessor.GetParameters().Length == 0
select new { Name=property.Name, Getter=accessor};
return nullableProperties.ToDictionary(
x => x.Name,
x => x.Getter.Invoke(DataObject, null).ToString());
}

How do I use reflection to get properties explicitly implementing an interface?

More specifically, if I have:
public class TempClass : TempInterface
{
int TempInterface.TempProperty
{
get;
set;
}
int TempInterface.TempProperty2
{
get;
set;
}
public int TempProperty
{
get;
set;
}
}
public interface TempInterface
{
int TempProperty
{
get;
set;
}
int TempProperty2
{
get;
set;
}
}
How do I use reflection to get all the propertyInfos for properties explicitly implementing TempInterface?
Thanks.
I think the class you are looking for is System.Reflection.InterfaceMapping.
Type ifaceType = typeof(TempInterface);
Type tempType = typeof(TempClass);
InterfaceMapping map = tempType.GetInterfaceMap(ifaceType);
for (int i = 0; i < map.InterfaceMethods.Length; i++)
{
MethodInfo ifaceMethod = map.InterfaceMethods[i];
MethodInfo targetMethod = map.TargetMethods[i];
Debug.WriteLine(String.Format("{0} maps to {1}", ifaceMethod, targetMethod));
}
The property getter and setter of an explicitly implemented interface property has an unusual attribute. It's IsFinal property is True, even when it is not a member of a sealed class. Try this code to verify my assertion:
foreach (AssemblyName name in Assembly.GetEntryAssembly().GetReferencedAssemblies()) {
Assembly asm = Assembly.Load(name);
foreach (Type t in asm.GetTypes()) {
if (t.IsAbstract) continue;
foreach (MethodInfo mi in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)) {
int dot = mi.Name.LastIndexOf('.');
string s = mi.Name.Substring(dot + 1);
if (!s.StartsWith("get_") && !s.StartsWith("set_")) continue;
if (mi.IsFinal)
Console.WriteLine(mi.Name);
}
}
}
Here's a modified solution based on the implementation given in this blog post:
var explicitProperties =
from prop in typeof(TempClass).GetProperties(
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)
let getAccessor = prop.GetGetMethod(true)
where getAccessor.IsFinal && getAccessor.IsPrivate
select prop;
foreach (var p in explicitProperties)
Console.WriteLine(p.Name);
Building on the answer by MrKurt:
var targetMethods =
from iface in typeof(TempClass).GetInterfaces()
from method in typeof(TempClass).GetInterfaceMap(iface).TargetMethods
select method;
var explicitProps =
from prop in typeof(TempClass).GetProperties(BindingFlags.Instance |
BindingFlags.NonPublic)
where targetMethods.Contains(prop.GetGetMethod(true)) ||
targetMethods.Contains(prop.GetSetMethod(true))
select prop;
I had to modify Jacob Carpenter's answer but it works nicely. nobugz's also works but Jacobs is more compact.
var explicitProperties =
from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
where method.IsFinal && method.IsPrivate
select method;
A simple helper class that could help:
public class InterfacesPropertiesMap
{
private readonly Dictionary<Type, PropertyInfo[]> map;
public InterfacesPropertiesMap(Type type)
{
this.Interfaces = type.GetInterfaces();
var properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
this.map = new Dictionary<Type, PropertyInfo[]>(this.Interfaces.Length);
foreach (var intr in this.Interfaces)
{
var interfaceMap = type.GetInterfaceMap(intr);
this.map.Add(intr, properties.Where(p => interfaceMap.TargetMethods
.Any(t => t == p.GetGetMethod(true) ||
t == p.GetSetMethod(true)))
.Distinct().ToArray());
}
}
public Type[] Interfaces { get; private set; }
public PropertyInfo[] this[Type interfaceType]
{
get { return this.map[interfaceType]; }
}
}
You'll get properties for each interface, even explicitly implemented.
It's overly complex. You have to reflect over the methods/properties of the Interface type, see if they exist in your class type, and compare them to see if they're the "same" when they do exist.
If something is in the interface but not the type you're testing, it's an explicit implementation. If it's in both, but different between the two, it's an explicit interface.
This seems a bit painful for no apparent reason!
My solution is for the case where you know the name of the property you are looking for and is pretty simple.
I have a class for making reflection a bit easier that I just had to add this case to:
public class PropertyInfoWrapper
{
private readonly object _parent;
private readonly PropertyInfo _property;
public PropertyInfoWrapper(object parent, string propertyToChange)
{
var type = parent.GetType();
var privateProperties= type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
var property = type.GetProperty(propertyToChange) ??
privateProperties.FirstOrDefault(p => UnQualifiedNameFor(p) == propertyName);
if (property == null)
throw new Exception(string.Format("cant find property |{0}|", propertyToChange));
_parent = parent;
_property = property;
}
private static string UnQualifiedNameFor(PropertyInfo p)
{
return p.Name.Split('.').Last();
}
public object Value
{
get { return _property.GetValue(_parent, null); }
set { _property.SetValue(_parent, value, null); }
}
}
You cant just do == on name because explicitly implemented properties have fully qualified names.
GetProperties needs both the search flags to get at private properties.
Jacob's code is missing a filter:
var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties());
foreach (var prop in props)
Console.WriteLine(prop);

Categories