Get value/obj ref in generic code by prop name - c#

I recently created generic sql command generating code. Everything works except one thing i currently struggle with.
How do i get the instance/the value of the Answer prop by the given property name?
What i have:
Question instance as object (for example myObject)
property of question + inner prop name (string) + inner class type
[Table("Question")]
public class Question
{
[Column("QuestionID", true)]
public int QuestionId { get; set; }
[Column("Number")]
public string Nr { get; set; }
[Column("CorrectAnswer", typeof(Answer), nameof(Answer.Text))]
public Answer CorrectAnswer { get; set; }
}
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
public class ColumnAttribute : DatabaseAttribute
{
public bool IsTechnicalId { get; private set; } = false;
public string DeepPropName { get; private set; } = null;
public Type DeepClass { get; private set; } = null;
public bool HasDeepProp { get; private set; } = false;
public ColumnAttribute(string name) : base(name)
{
}
/// <summary>
/// Creates a deep object property column definition
/// </summary>
/// <param name="name"></param>
/// <param name="deepProperty"></param>
public ColumnAttribute(string name, Type deepClass, string deepPropertyName) : base(name)
{
DeepPropName = deepPropertyName;
DeepClass = deepClass;
HasDeepProp = true;
}
public ColumnAttribute(string name, bool isTechnicalId) : this(name)
{
IsTechnicalId = isTechnicalId;
}
}
My current code for getting the props and the values looks like this.
public static IEnumerable<DatabaseAttributeContainer> GetAllAttributes<TClass>(TClass obj, bool inherit = false)
{
List<DatabaseAttributeContainer> propValues = new List<DatabaseAttributeContainer>();
object value = null;
Type classType = typeof(TClass);
PropertyInfo[] pInfos = inherit ? classType.GetProperties() : classType.GetProperties(_NonInheritedFlag);
DatabaseAttribute[] attributes = null;
DatabaseAttribute attr = null;
ColumnAttribute colAttr = null;
PropertyInfo[] pInfosDeep = null;
foreach (PropertyInfo pInfo in pInfos)
{
attributes = (DatabaseAttribute[])pInfo.GetCustomAttributes(typeof(DatabaseAttribute));
attr = attributes.FirstOrDefault();
if(!(attr is IgnoreAttribute))
{
colAttr = (ColumnAttribute)attr;
//broken
if(colAttr.HasDeepProp)
{
pInfosDeep = colAttr.DeepClass.GetProperties(_NonInheritedFlag);
foreach (PropertyInfo pInfoDeep in pInfosDeep)
{
if(pInfoDeep.Name == colAttr.DeepPropName)
{
//Need object instance of Answer for "GetValue()"
//value = pInfoDeep.GetValue(obj, null);
break;
}
}
}
//broken end
else
{
if (obj != null)
value = pInfo.GetValue(obj, null);
propValues.Add(new DatabaseAttributeContainer(attr, value));
}
}
}
propValues.Add(GetAttributeByClass<TClass>());
if (propValues.Count == 0)
throw new ApplicationException(typeof(TClass) + "has no DatabaseAttribute attribute");
return propValues;
}
Everything works perfectly with the only exception: How to get the property value of another object inside the object im searching for?
Am i able to get any instance of a property of an instanced object?
Edit1:
I could get the ref by
if(pInfo.Name == "CorrectAnswer")
answerRef = pInfo.GetValue(obj, null);
and than get the props from the answerRef castet to answer to get the value
for my given propName

Solution
public static IEnumerable<DatabaseAttributeContainer> GetAllAttributes<TClass>(TClass obj, bool inherit = false)
{
List<DatabaseAttributeContainer> propValues = new List<DatabaseAttributeContainer>();
object value = null;
Type classType = typeof(TClass);
PropertyInfo[] pInfos = inherit ? classType.GetProperties() : classType.GetProperties(_NonInheritedFlag);
DatabaseAttribute[] attributes = null;
DatabaseAttribute attr = null;
ColumnAttribute colAttr = null;
PropertyInfo pInfoDeep = null;
object deepRef = null;
//ToDo: get custom attributes from this obj and iterate over it with prop name
//get propInfo (performance increase)
foreach (PropertyInfo pInfo in pInfos)
{
attributes = (DatabaseAttribute[])pInfo.GetCustomAttributes(typeof(DatabaseAttribute));
attr = attributes.FirstOrDefault();
if (!(attr is IgnoreAttribute))
{
colAttr = attr as ColumnAttribute;
if (colAttr != null && colAttr.HasDeepProp && obj != null)
{
//get ref value
deepRef = pInfo.GetValue(obj, null);
deepRef = Convert.ChangeType(deepRef, colAttr.DeepType);
pInfoDeep = deepRef.GetType().GetProperty(colAttr.DeepPropName);
if (pInfoDeep == null)
throw new ApplicationException("Property with name " + colAttr.DeepPropName + " not found");
value = pInfoDeep.GetValue(deepRef, null);
}
else
{
if (obj != null)
value = pInfo.GetValue(obj, null);
}
propValues.Add(new DatabaseAttributeContainer(attr, value));
}
}
propValues.Add(GetAttributeByClass<TClass>());
if (propValues.Count == 0)
throw new ApplicationException(typeof(TClass) + "has no DatabaseAttribute attribute");
return propValues;
}

Related

How to get/set value of properties using string property paths?

Let's say we have a class Root that has BasicDetails class property and then basicDetails has two properties. A string "Name" and a dynamic object called "CustomAttributes".
I want to get the value in the following manner:
var root = new Root();
root.BasicDetails.Name = "Samurai";
root.BasicDetails.CustomAttributes.phone = "12345";
string res1 = GetDeepPropertyValue(root, "BasicDetails.CustomAttributes.Phone").ToString();
string res2 = GetDeepPropertyValue(root, "BasicDetails.Name").ToString();
The following is the code I have tried (based on another answer on SO):
public static object GetDeepPropertyValue(object src, string propName)
{
if (propName.Contains('.'))
{
string[] Split = propName.Split('.');
string RemainingProperty = propName.Substring(propName.IndexOf('.') + 1);
return GetDeepPropertyValue(src.GetType().GetProperty(Split[0]).GetValue(src, null), RemainingProperty);
}
else
return src.GetType().GetProperty(propName).GetValue(src, null);
}
The following are the classes:
public class Root
{
public Root()
{
BasicDetails = new BasicDetails();
}
public BasicDetails BasicDetails { get;set;}
}
public class BasicDetails
{
public BasicDetails()
{
CustomAttributes = new ExpandoObject();
}
public string Name { get; set; }
public dynamic CustomAttributes { get; set; }
}
The function that I have tried is throwing null reference error. Unfortunately I do not understand reflection too well so at the moment I am monkey patching. If someone could please explain c#how this can be done it would be great. Thank you in advance.
Following method gets values from nested properties:
public static object GetPropertyValue(object src, string propName)
{
if (src == null) throw new ArgumentException("Value cannot be null.", "src");
if (propName == null) throw new ArgumentException("Value cannot be null.", "propName");
if (propName.Contains("."))//complex type nested
{
var temp = propName.Split(new char[] { '.' }, 2);
return GetPropertyValue(GetPropertyValue(src, temp[0]), temp[1]);
}
else
{
if (src is ExpandoObject)
{
var expando = src as IDictionary<string, object>;
if (expando != null)
{
object obj;
expando.TryGetValue(propName, out obj);
return obj;
}
return null;
}
else
{
var prop = src.GetType().GetProperty(propName);
return prop != null ? prop.GetValue(src, null) : null;
}
}
}
Usage:
string res1 = GetPropertyValue(root, "BasicDetails.CustomAttributes.phone") as string;
string res2 = GetPropertyValue(root, "BasicDetails.Name") as string;

.Net reflection to get nested property with custom attribute

I want to know the best way to get the prop info and value using reflection for a nested class by its custom attribute name.
With below code I can get the prop info via recursion. But is there a better way or using LINQ. Note that I do not want to hard code the class type as similar to other solution
I also want to get the property value by custom attribute
e.g var propValue = ?????
public class PlanetRoot
{
public void GetNeighborMoon()
{
Planet planet = new Planet();
Product product = new Product();
Neighbor neighbor = new Neighbor();
neighbor.Moons = 10;
neighbor.RingColor = "Red";
product.Neighbors = new List<Neighbor>();
product.Neighbors.Add(neighbor);
planet.Product = product;
//1. Get the RingColor property info of neighbor with attribute MyDBField(Name = "NeighborRing") . Is there a better way
PropertyInfo propInfo = null;
DoRecursiveGetProperty(planet.GetType(), "NeighborRing", out propInfo );
//2. Get the RingColor property value of neighbor with attribute MyDBField(Name = "NeighborRing")
//var propValue = GetPropertyValue(????);
}
}
private static PropertyInfo DoRecursiveGetProperty(Type type, string attribName, out PropertyInfo propInfo)
{
PropertyInfo[] pi = type.GetProperties();
propInfo= null;
foreach (PropertyInfo p in pi)
{
var dbFieldAttribute = (MyDBFieldAttribute)Attribute.GetCustomAttribute(p, typeof(MyDBFieldAttribute));
if (dbFieldAttribute != null && attribName.ToUpper() == dbFieldAttribute.Name.ToUpper())
{
propInfo= p;
//Console.WriteLine(p.Name + " : " + (dbFieldAttribute != null && dbFieldAttribute.Name != null ? dbFieldAttribute.Name : "****"));
return true;
}
if (p.PropertyType.IsClass && !p.PropertyType.IsValueType && !p.PropertyType.IsPrimitive
&& p.PropertyType.FullName != "System.String")
if (propInfo != null) return true;
else DoRecursiveGetProperty(p.PropertyType, attribName, out propInfo);
}
return false;
}
public class Planet
{
public string PlanetId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Product Product { get; set; }
[MyDBField(Name="PubDate")]
public string Publishdate { get; set; }
}
public class Product
{
public string ProductId { get; set; }
public List<Neighbor> Neighbors { get; set; }
}
public class Neighbor
{
[MyDBField(Name = "NeighborRing")]
public string RingColor { get; set; }
public int Moons { get; set; }
}
public class MyDBFieldAttribute : System.Attribute
{
public string Name { get; set; }
}
In order to get the value for a nested member that might be in a collection, you need to iterate the collections, and track the current object.
Assuming you don't need the resulting PropInfo for other reasons, just try to get the value:
private static bool TryRecursiveGetValueWithMyDBFieldName(object startObject, string attribName, out object propValue) {
PropertyInfo[] pi = startObject.GetType().GetProperties();
foreach (PropertyInfo p in pi) {
var dbFieldAttribute = (MyDBFieldAttribute)Attribute.GetCustomAttribute(p, typeof(MyDBFieldAttribute));
if (dbFieldAttribute != null && dbFieldAttribute.Name.Equals(attribName, StringComparison.CurrentCultureIgnoreCase)) {
//Console.WriteLine(p.Name + " : " + (dbFieldAttribute != null && dbFieldAttribute.Name != null ? dbFieldAttribute.Name : "****"));
propValue = p.GetValue(startObject);
return true;
}
if (p.PropertyType.IsClass && !p.PropertyType.IsValueType && !p.PropertyType.IsPrimitive &&
!p.PropertyType.FullName.StartsWith("System.")) {
var tryObject = p.GetValue(startObject);
if (tryObject != null && TryRecursiveGetValueWithMyDBFieldName(tryObject, attribName, out propValue))
return true;
}
if (p.PropertyType.IsClass && p.GetValue(startObject) is IEnumerable ip) {
foreach (var obj in ip) {
if (obj != null && TryRecursiveGetValueWithMyDBFieldName(obj, attribName, out propValue))
return true;
}
}
}
propValue = default;
return false;
}
To use it, call with the initial object:
var foundAttrib = TryRecursiveGetValueWithMyDBFieldName(planet, "NeighborRing", out var propValue);
NOTE: This will return the value of the first object with a matching attribute, as e.g. every member of the List<Neighbor> member will have the MyDBField attribute with the Name property of NeighborRing.

Converting Flat file to List which is a property of another class

public class DummyResponse
{
public int UpdatedRecords { get; set; }
public string Id { get; set; }
public bool Isvalid { get; set; }
}
public class Request
{
public List<DummyResponse> Changes { get; set; }
public string ReuestedBy { get; set; }
public Request()
{
Changes = new List<DummyResponse>();
}
}
I have a flat file which contains tab separated data for Dummy Response.
I want this to be serialized to Request object.
The implementation needs should be generic as in I only need user to pass T (Request) in this case and identify the correct sub type to be filled from flat file.
I have below Code to convert it into Object. How ever its only working for properties having string type.
interface ICollectionBuilder
{
object Build(IList dictionaries);
}
internal class CollectionBuilder<T> : ICollectionBuilder where T : new()
{
public object Build(IList dictionaries)
{
var dictConverter = new DictionaryConerter<T>();
return dictionaries
.OfType<IDictionary<string, object>>()
.Select(dict => dictConverter.ConvertTyped(dict))
.ToList();
}
}
interface IDictionaryConverter
{
object Convert(IDictionary<string, object> dict);
}
internal class DictionaryConerter<T> : IDictionaryConverter where T : new()
{
public object Convert(IDictionary<string, object> dict)
{
return ConvertTyped(dict);
}
public T ConvertTyped(IDictionary<string, object> dict)
{
T t = new T();
var properties = t.GetType().GetProperties();
foreach (KeyValuePair<string, object> curr in dict)
{
if (String.IsNullOrEmpty(curr.Key)) continue;
if (curr.Value == null) continue;
Type valType = null;
Type newType = null;
PropertyInfo currProperty = null;
foreach (PropertyInfo p in properties)
{
if (String.IsNullOrEmpty(p.Name)) continue;
if (String.Compare(p.Name.ToLower(), curr.Key.ToLower()) == 0)
{
valType = t.GetType().GetProperty(p.Name).PropertyType;
newType = Nullable.GetUnderlyingType(valType) ?? valType;
currProperty = p;
break;
}
}
object newVal = curr.Value;
var curDict = curr.Value as IDictionary<string, object>;
var curList = curr.Value as IList;
if (curDict != null && newType.GetConstructor(Type.EmptyTypes) != null)
{
newVal = ((IDictionaryConverter)Activator.CreateInstance(typeof(DictionaryConerter<>).MakeGenericType(newType))).Convert(curDict);
}
else if (
curList != null &&
curList.OfType<IDictionary<string, object>>().Any() &&
newType.IsGenericType &&
newType.GetGenericTypeDefinition() == typeof(List<>) &&
newType.GetGenericArguments()[0].GetConstructor(Type.EmptyTypes) != null)
{
newVal = ((ICollectionBuilder)Activator.CreateInstance(typeof(CollectionBuilder<>).MakeGenericType(newType.GetGenericArguments()[0]))).Build(curList);
}
t.GetType().GetProperty(currProperty.Name).SetValue(t, newVal);
}
return t;
}
}
Example usage:
void Main ()
{
var dict = new Dictionary<string,object>();
dict.Add("ReuestedBy",abc);
var innerDict = new Dictionary<string,object>();
var list = new LIst<Dictionary<string,object>>();
innerDict.Add("UpdatedRecords","45");
innerDict.Add("Id","1");
innerDict.Add("IsValid","False");
dict.Add("Changes",list )
}
The problem here is it not working for any other type other than string.
I fixed it using below code while setting value
propertyVal = Convert.ChangeType(propertyVal, targetType);
propertyInfo.SetValue(inputObject, propertyVal, null);

How to get all names and values of any object using reflection and recursion

I am trying to get a property names and values from an instance of an object. I need it to work for objects that contain nested objects where I can simple pass in the the parent instance.
For example, if I have:
public class ParentObject
{
public string ParentName { get; set; }
public NestedObject Nested { get; set; }
}
public class NestedObject
{
public string NestedName { get; set; }
}
// in main
var parent = new ParentObject();
parent.ParentName = "parent";
parent.Nested = new NestedObject { NestedName = "nested" };
PrintProperties(parent);
I have attempted a recursive method:
public static void PrintProperties(object obj)
{
var type = obj.GetType();
foreach (PropertyInfo p in type.GetProperties())
{
Console.WriteLine(p.Name + ":- " + p.GetValue(obj, null));
if (p.PropertyType.GetProperties().Count() > 0)
{
// what to pass in to recursive method
PrintProperties();
}
}
Console.ReadKey();
}
How do I determine that the property is then what is passed in to the PrintProperties?
You get the value already, try this:
object propertyValue = p.GetValue(obj, null);
Console.WriteLine(p.Name + ":- " + propertyValue);
if (p.PropertyType.GetProperties().Count() > 0)
{
// what to pass in to recursive method
PrintProperties(propertyValue);
}
To fix this issue you can use this code with a little fix
private Dictionary<string, string> GetAllProperties(object objectItem, Dictionary<string, string> result)
{
if (objectItem == null || objectItem.GetType().IsPrimitive)
{
return result;
};
try
{
Type objType = objectItem.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(objectItem, null);
if (propValue == null)
{
continue;
}
if (propValue is IList subPropValues)
{
foreach (var item in subPropValues)
{
GetAllProperties(item, result);
}
}
else
{
// This will not cut-off System.Collections because of the first check
if (property.PropertyType.Assembly == objType.Assembly)
{
GetAllProperties(propValue, result);
}
else
{
if (IsValidPrimaryType(propValue))
{
result.Add($"{objectItem.GetType().Name}:{property.Name}", propValue.ToString());
}
}
}
}
}
catch
{
return result;
}
return result;
}
use it
var myObject = yourObject;
var myPropsAndValues = new Dictionary<string, string>();
GetAllProperties(myObject, myPropsAndValues);

c# - How to iterate through classes fields and set properties

I am not sure if this is possible but I want to iterate through a class and set a field member property without referring to the field object explicitly:
public class Employee
{
public Person _person = new Person();
public void DynamicallySetPersonProperty()
{
MemberInfo[] members = this.GetType().GetMembers();
foreach (MemberInfo member in members.Where(a => a.Name == "_person"))
//get the _person field
{
Type type = member.GetType();
PropertyInfo prop = type.GetProperty("Name"); //good, this works, now to set a value for it
//this line does not work - the error is "property set method not found"
prop.SetValue(member, "new name", null);
}
}
}
public class Person
{
public string Name { get; set; }
}
In the answer that I marked as the answer you need to add:
public static bool IsNullOrEmpty(this string source)
{
return (source == null || source.Length > 0) ? true : false;
}
Here's a complete working example:
public class Person
{
public string Name { get; set; }
}
class Program
{
static void PropertySet(object p, string propName, object value)
{
Type t = p.GetType();
PropertyInfo info = t.GetProperty(propName);
if (info == null)
return;
if (!info.CanWrite)
return;
info.SetValue(p, value, null);
}
static void PropertySetLooping(object p, string propName, object value)
{
Type t = p.GetType();
foreach (PropertyInfo info in t.GetProperties())
{
if (info.Name == propName && info.CanWrite)
{
info.SetValue(p, value, null);
}
}
}
static void Main(string[] args)
{
Person p = new Person();
PropertySet(p, "Name", "Michael Ellis");
Console.WriteLine(p.Name);
PropertySetLooping(p, "Name", "Nigel Mellish");
Console.WriteLine(p.Name);
}
}
EDIT: added a looping variant so you could see how to loop through property info objects.
public class Person
{
public string Name { get; set; }
}
public class Employee
{
public Person person = new Person();
public void DynamicallySetPersonProperty()
{
var p = GetType().GetField("person").GetValue(this);
p.GetType().GetProperty("Name").SetValue(p, "new name", null);
}
}
With the following Extension methods that I have created, you can set or get any property value even if they are nested
GetPropertyValue(customObject, "Property.Nested.Child.Name");
or set
SetPropertyValue(customObject, "Property.Nested.Child.Name", "my custom name");
private class TargetProperty
{
public object Target { get; set; }
public PropertyInfo Property { get; set; }
public bool IsValid { get { return Target != null && Property != null; } }
}
private static TargetProperty GetTargetProperty(object source, string propertyName)
{
if (!propertyName.Contains("."))
return new TargetProperty { Target = source, Property = source.GetType().GetProperty(propertyName) };
string[] propertyPath = propertyName.Split('.');
var targetProperty = new TargetProperty();
targetProperty.Target = source;
targetProperty.Property = source.GetType().GetProperty(propertyPath[0]);
for (int propertyIndex = 1; propertyIndex < propertyPath.Length; propertyIndex++)
{
propertyName = propertyPath[propertyIndex];
if (!string.IsNullOrEmpty(propertyName))
{
targetProperty.Target = targetProperty.Property.GetValue(targetProperty.Target, null);
targetProperty.Property = targetProperty.Target.GetType().GetProperty(propertyName);
}
}
return targetProperty;
}
public static bool HasProperty(this object source, string propertyName)
{
return GetTargetProperty(source, propertyName).Property != null;
}
public static object GetPropertyValue(this object source, string propertyName)
{
var targetProperty = GetTargetProperty(source, propertyName);
if (targetProperty.IsValid)
{
return targetProperty.Property.GetValue(targetProperty.Target, null);
}
return null;
}
public static void SetPropertyValue(this object source, string propertyName, object value)
{
var targetProperty = GetTargetProperty(source, propertyName);
if(targetProperty.IsValid)
{
targetProperty.Property.SetValue(targetProperty.Target, value, null);
}
}
And here are a couple of tests for it
[TestFixture]
public class ObjectExtensionsTest
{
private class MockClass
{
public MockClass()
{
Nested = new NestedMockClass();
}
public string Id { get; set; }
public string Name { get; set; }
public string GetOnly { get { return "MockClass"; } }
public string SetOnly { set { } }
public NestedMockClass Nested { get; set; }
}
private class NestedMockClass
{
public string NestedId { get; set; }
public string NestedName { get; set; }
public string NestedGetOnly { get { return "NestedMockClass"; } }
public string NestedSetOnly { set { } }
}
[Test]
public void TestShouldFindProperty()
{
MockClass mockObject = new MockClass();
Assert.IsTrue(mockObject.HasProperty("Id"));
Assert.IsTrue(mockObject.HasProperty("Name"));
Assert.IsTrue(mockObject.HasProperty("GetOnly"));
Assert.IsTrue(mockObject.HasProperty("SetOnly"));
Assert.IsTrue(mockObject.HasProperty("Nested"));
Assert.IsTrue(mockObject.HasProperty("Nested.NestedId"));
Assert.IsTrue(mockObject.HasProperty("Nested.NestedName"));
Assert.IsTrue(mockObject.HasProperty("Nested.NestedGetOnly"));
Assert.IsTrue(mockObject.HasProperty("Nested.NestedSetOnly"));
}
[Test]
public void TestShouldGetPropertyValue()
{
MockClass mockObject = new MockClass();
mockObject.Id = "1";
mockObject.Name = "Name";
mockObject.Nested.NestedId = "NestedId";
mockObject.Nested.NestedName = "NestedName";
Assert.AreEqual(mockObject.Id, mockObject.GetPropertyValue("Id"));
Assert.AreEqual(mockObject.Name, mockObject.GetPropertyValue("Name"));
Assert.AreEqual(mockObject.GetOnly, mockObject.GetPropertyValue("GetOnly"));
Assert.AreEqual(mockObject.Nested.NestedId, mockObject.GetPropertyValue("Nested.NestedId"));
Assert.AreEqual(mockObject.Nested.NestedName, mockObject.GetPropertyValue("Nested.NestedName"));
}
[Test]
public void TestShouldSetPropertyValue()
{
MockClass mockObject = new MockClass();
mockObject.SetPropertyValue("Id", "1");
mockObject.SetPropertyValue("Name", "Name");
mockObject.SetPropertyValue("Nested.NestedId", "NestedId");
mockObject.SetPropertyValue("Nested.NestedName", "NestedName");
Assert.AreEqual(mockObject.Id, "1");
Assert.AreEqual(mockObject.Name, "Name");
Assert.AreEqual(mockObject.Nested.NestedId, "NestedId");
Assert.AreEqual(mockObject.Nested.NestedName, "NestedName");
}
}
Hope you find it useful.
You are trying to set the Name property of your Employee class's _person field. It doesn't have one. Try this:
prop.SetValue(((FieldInfo)member).GetValue(this), "new name", null)
Not sure if you need to cast the first argument like this:
prop.SetValue((Person)((FieldInfo)member).GetValue(this), "new name", null)
This then applies it to the value of the _person field instead.
You a trying to perform SetValue() on the property Name of the variable member that is a MemberInfo object and this proeprty is read only.
Note you do not need to iterate over all memebers and you do not need to get the field _person with reflection as it is defined in the same class as the method DynamicallySetPersonProperty().
So the code shoul read like this.
PropertyInfo property = this._person.GetType().GetProperty("Name");
property.SetValue(this._person, "new name", null);
The first line will fail if _person is null. So you can use reflectiopn to get the type of the field.
FieldInfo field = this.GetType().GetField("_person", BindingFlags.Public);
PropertyInfo property = field.FieldType.GetProperty("Name");
But now accessing this property will still fail if _personis null.
property.Setvalue(field.GetValue(this), "new name", null);
try this:
public static void ApplyPropertyChanges(this object objDest, object objToCopyFrom)
{
if (objDest == null)
throw new ArgumentNullException();
if (objToCopyFrom == null)
throw new ArgumentNullException("objToCopyFrom");
if (objDest.GetType() != objToCopyFrom.GetType())
throw new Exception("Invalid type. Required: \"" + objDest.GetType().ToString() + "\"");
foreach (System.Reflection.PropertyInfo piOrig in objDest.GetType().GetProperties())
{
object editedVal = objToCopyFrom.GetType().GetProperty(piOrig.Name).GetValue(objToCopyFrom, null);
piOrig.SetValue(objDest,
editedVal,
null);
}
}
usage example:
public ActionResult Edit(Team editedTeamData)
{
if (!ModelState.IsValid)
return View();
Team origTeam = (from t in _db.Teams
where t.TeamID == editedTeamData.TeamID
select t).FirstOrDefault();
origTeam.ApplyPropertyChanges(editedTeamData);
_db.SubmitChanges();
return RedirectToAction("Index");
}

Categories

Resources