Object must implement IConvertible when converting Array to Object Class [duplicate] - c#

foreach (var filter in filters)
{
var filterType = typeof(Filters);
var method = filterType.GetMethod(filter, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Static);
if (method != null)
{
var parameters = method.GetParameters();
Type paramType = parameters[0].ParameterType;
value = (string)method.Invoke(null, new[] { value });
}
}
How can I cast value to paramType? value is a string, paramType will probably just be a basic type like int, string, or maybe float. I'm cool with it throwing an exception if no conversion is possible.

The types you are using all implement IConvertible. As such you can use ChangeType.
value = Convert.ChangeType(method.Invoke(null, new[] { value }), paramType);

You could go dynamic; for example:
using System;
namespace TypeCaster
{
class Program
{
internal static void Main(string[] args)
{
Parent p = new Parent() { name = "I am the parent", type = "TypeCaster.ChildA" };
dynamic a = Convert.ChangeType(new ChildA(p.name), Type.GetType(p.type));
Console.WriteLine(a.Name);
p.type = "TypeCaster.ChildB";
dynamic b = Convert.ChangeType(new ChildB(p.name), Type.GetType(p.type));
Console.WriteLine(b.Name);
}
}
internal class Parent
{
internal string type { get; set; }
internal string name { get; set; }
internal Parent() { }
}
internal class ChildA : Parent
{
internal ChildA(string name)
{
base.name = name + " in A";
}
public string Name
{
get { return base.name; }
}
}
internal class ChildB : Parent
{
internal ChildB(string name)
{
base.name = name + " in B";
}
public string Name
{
get { return base.name; }
}
}
}

Related

C# recursively check all values not null

Without wanting to reinvent the wheel, is there a .NET NuGet library to perform checks on a object recursively for argument checking?
If not, how would I convert the code to check if a property is null, and if a type that can hold properties of its own, recursively check that type, and end up with a list of property names that are null.
public static class Assert
{
public static void AllPropertiesNotNull<T>(T obj)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
var emptyProperties = typeof(T)
.GetProperties()
.Select(prop => new { Prop = prop, Val = prop.GetValue(obj, null) })
.Where(val => IsEmpty((dynamic)val.Val))
.Select(val => val.Prop.Name)
.ToList();
if (emptyProperties.Count > 0)
throw new ArgumentNullException(emptyProperties.First());
}
private static bool IsEmpty(object o) { return o == null; }
}
Note: You should do null checking on constructor parameters or method parameters and throw exception when the parameter is unexpectedly null. It's better to follow the common best practices.
Anyway, here is an example showing how you can check all properties of an object recursively using an extension method and throw exception of finding null properties...
You can create an extension method ThrowOnNullProperty for object and use it like this:
something.ThrowOnNullProperty();
Here is an implementation of such extension method:
If the passed object is null, throw exception.
If the object is a primitive type or a string, continue.
If the object has been visited before, then continue, otherwise add it to list of visited objects.
Check first level properties of the object and if there are null properties, throw an exception containing name of the null properties.
If the first level properties are not null, the for each property value go to 1.
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
public static class ObjectExtensions
{
public static void ThrowOnNullProperty(this object obj)
{
ThrowOnNullProperty(obj, new HashSet<object>());
}
private static void ThrowOnNullProperty(object obj, HashSet<object> visitedObjects)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
if (obj.GetType().IsPrimitive || obj.GetType() == typeof(string))
return;
if (visitedObjects.Contains(obj))
return;
visitedObjects.Add(obj);
var nullPropertyNames = obj.GetType().GetProperties()
.Where(p => p.GetValue(obj) == null)
.Select(p => p.Name);
if (nullPropertyNames.Any())
throw new ArgumentException(
$"Null properties: {string.Join(",", nullPropertyNames)}");
var notNullPropertyValues = obj.GetType().GetProperties()
.Select(p => p.GetValue(obj))
.Where(v => v != null);
foreach (var item in notNullPropertyValues)
ThrowOnNullProperty(item, visitedObjects);
}
}
To do so, write a method to check the properties of current object and call it recursively on the non-null properties. I went ahead and wrote some code, which includes looping over dictionaries and enumerables and checking them for nulls also, taking into account circular references as mentioned by #dcg.
static readonly HashSet<Type> excludedTypes = new HashSet<Type>{ typeof(string) };
public static List<string> AllPropertiesNotNull(IDictionary dictionary, string name, HashSet<object> alreadyChecked)
{
List<string> nullValues = new List<string>();
foreach(object key in dictionary.Keys)
{
object obj = dictionary[key];
if (!alreadyChecked.Contains(obj))
{
string elementName = $"{name}[\"{key}\"]";
nullValues.AddRange(AllPropertiesNotNull(obj, elementName, alreadyChecked));
}
}
return nullValues;
}
public static List<string> AllPropertiesNotNull(IEnumerable enumerable, string name, HashSet<object> alreadyChecked)
{
List<string> nullValues = new List<string>();
int i = 0;
foreach (object obj in enumerable)
{
if (!alreadyChecked.Contains(obj))
{
string elementName = $"{name}[{i}]";
nullValues.AddRange(AllPropertiesNotNull(obj, elementName, alreadyChecked));
}
i++;
}
return nullValues;
}
public static List<string> AllPropertiesNotNull(object obj, string name, HashSet<object> alreadyChecked, string baseName = "")
{
List<string> nullValues = new List<string>();
string basePropertyName;
if (string.IsNullOrEmpty(baseName))
{
basePropertyName = name;
}
else
{
basePropertyName = baseName + "." + name;
}
if (obj == null)
{
nullValues.Add(basePropertyName);
}
else if (!alreadyChecked.Contains(obj))
{
alreadyChecked.Add(obj);
if (!excludedTypes.Contains(obj.GetType()))
{
foreach (PropertyInfo property in obj.GetType().GetProperties())
{
object value = property.GetValue(obj);
string propertyName = basePropertyName + "." + property.Name;
if (value == null)
{
nullValues.Add(propertyName);
}
else
{
if (typeof(IDictionary).IsAssignableFrom(property.PropertyType))
{
nullValues.AddRange(AllPropertiesNotNull((IDictionary)value, propertyName, alreadyChecked));
}
else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
{
nullValues.AddRange(AllPropertiesNotNull((IEnumerable)value, propertyName, alreadyChecked));
}
else
{
nullValues.AddRange(AllPropertiesNotNull(value, property.Name, alreadyChecked, basePropertyName));
}
}
}
}
}
return nullValues;
}
I wrote some classes to test with:
class A
{
public string s1 { set; get; }
public string s2 { set; get; }
public int i1 { set; get; }
public int? i2 { set; get; }
public B b1 { set; get; }
public B b2 { set; get; }
}
class B
{
public string s1 { set; get; }
public string s2 { set; get; }
public int i1 { set; get; }
public int? i2 { set; get; }
public A a1 { set; get; }
public Dictionary<int, string> d1 { set; get; }
public List<A> l1 { set; get; }
}
and tested it as follows:
A a = new A
{
s1 = "someText"
};
B b = new B
{
s1 = "someText",
a1 = a,
d1 = new Dictionary<int, string>
{
{ 1, "someText" },
{ 2, null }
},
l1 = new List<A>{ null, new A { s1 = "someText" } , a }
};
a.b1 = b;
Console.WriteLine(string.Join("\n", AllPropertiesNotNull(a, nameof(a), new HashSet<object>())));
Output:
a.s2
a.i2
a.b1.s2
a.b1.i2
a.b1.d1["2"]
a.b1.l1[0]
a.b1.l1[1].s2
a.b1.l1[1].i2
a.b1.l1[1].b1
a.b1.l1[1].b2
a.b2
Few points to take note of:
Only public properties are considered, use BindingFlags if you want to consider non-public ones.
Some types might need to be individually considered (e.g.: string) or maybe not (depending on your own case).
As mentioned before, the code loops on dictionaries and enumerables and checks every value for them too. You might or might not want that (depending on your own case).

Get type name of object and property name?

I need function, that returns {obj type name}.{property name}.{property name}..
For example:
class City {
public string Name {get;set;}
}
class Country {
public string Name {get;set;}
public City MyCity {get;set;}
}
var myCountry = new Country() {
Name="Ukraine",
MyCity = new City() {
Name = "Kharkov"
}
}
So my function should return "{Country.Name}" or "{Country.MyCity.Name}" depends on input parameter. What is the way to do it?
Use .net reflection
http://www.codersource.net/microsoftnet/cbasicstutorials/cnettutorialreflection.aspx
Create an IPrintable facade and use a recursive function Print(). Try to catch the idea and modify code for your concrete task. Hope, my example will be helpfull for you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StackOverflow
{
interface IPrintable
{
string Name { get; }
}
class City : IPrintable
{
public string Name { get; set; }
}
class Country : IPrintable
{
public string Name { get; set; }
public City MyCity { get; set; }
}
class Program
{
static void Main(string[] args)
{
var myCountry = new Country()
{
Name = "Ukraine",
MyCity = new City()
{
Name = "Kharkov"
}
};
Console.WriteLine(Print(myCountry, #"{{{0}}}"));
Console.WriteLine(Print(new City()
{
Name = "New-York"
}, #"{{{0}}}"));
}
private static string Print(IPrintable printaleObject, string formatter)
{
foreach (var prop in printaleObject.GetType().GetProperties())
{
object val = prop.GetValue(printaleObject, null);
if (val is IPrintable)
{
return String.Format(formatter, printaleObject.Name) + Print((IPrintable)val, formatter);
}
}
return String.Format(formatter, printaleObject.Name);
}
}
}
You didn't post much info on the requirement but, if you know your object type then there is no need to use Reflection, you can test with is like this:
if(returnCity && myObject is Country) //I'm assuming that the input value is boolean but, you get the idea...
{
return myObject.City.Name;
}
else
{
return myObject.Name;
}
Now, if you want to use Reflection, you can do something among these lines:
public static string GetNameFrom( object myObject )
{
var t = myObject.GetType();
if( t == typeof(Country) )
{
return ((Country)myObject).City.Name;
}
return ((City)myObject).Name;
}
Or, a more generic approach:
static string GetNameFrom( object myObject )
{
var type = myObject.GetType();
var city = myObject.GetProperty( "City" );
if( city != null)
{
var cityVal = city.GetValue( myObject, null );
return (string)cityVal.GetType().GetProperty( "Name" ).GetValue( cityVal, null );
}
return (string)type.GetProperty( "Name" ).GetValue( myObject, null );
}

Reading properties of hierarchical classes generically using reflection in C#

I have a set of classes that are generated via xsd.exe based on *.xsd files. Each set of classes generated for each set of *.xsd files are almost the same, except that there are a few properties different in each class. For example, in both set 1 and set 2, Shape class might have different property.
I want to use a method to read the value of specified properties (UPDATE) of all classes in one set at a time (Update). There could be many levels of class. The method (e.g. GetProperty method) should only know about its parameter type, and the string representation of all properties. The method only read property.
Is there a better way of doing this:
internal class DynPropertyTest
{
public static void Set1Test()
{
Shape shape = new Shape()
{
Name = "Shape",
Shape2 = new Shape2()
{
Name = "Shape2",
Shape3 = new Shape3() { Name = "Shape3" }
}
};
GetProperty(shape);
}
public static void Set2Test() {
...
}
UPDATE
I would like to know an alternative way to achieve the similar function to the the method below
//Should store all properties value in a collection, rather than display it
//And somehow store/know the type of the property.
public static void GetProperty(ShapeBase shape)
{
//shape.Name
Console.WriteLine(shape.GetType().GetProperty("Name").GetValue(shape, null));
//Shape.Shape2
object shape2 = shape.GetType().GetProperty("Shape2").GetValue(shape, null);
Console.WriteLine(shape2);
//Shape.Shape2.Name
object shape2Name = shape.GetType().GetProperty("Shape2").PropertyType.GetProperty("Name")
.GetValue(shape2, null);
Console.WriteLine(shape2Name);
//shape.shape2.shape3
object shape3 = shape2.GetType().GetProperty("Shape3").GetValue(shape2, null);
Console.WriteLine(shape3);
//shape.shape2.shape3.Name
object shape3Name = shape2.GetType().GetProperty("Shape3").PropertyType.GetProperty("Name")
.GetValue(shape3, null);
Console.WriteLine(shape3Name);
}
}
abstract class ShapeBase { }
//Example only.
namespace Set1
{
class Shape : ShapeBase
{
public string Name { get; set; }
public Shape2 Shape2 { get; set; }
}
class Shape2
{
public string Name { get; set; }
public Shape3 Shape3 { get; set; }
}
class Shape3
{
public string Name { get; set; }
}
}
namespace Set2
{
class Shape : ShapeBase{}
...
}
This is how we implement this functionality (this is for getting a String value for dynamic SQL, but you should be able to apply it to your situation:
public static string GetFieldValueForSQL(object oRecord, string sName)
{
PropertyInfo theProperty = null;
FieldInfo theField = null;
System.Type oType = null;
try
{
oType = oRecord.GetType();
// See if the column is a property in the record
theProperty = oType.GetProperty(sName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public, null, null, new Type[0], null);
if (theProperty == null)
{
theField = oType.GetField(sName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
if (theField != null)
{
return theField.GetValue(oRecord).ToString();
}
}
else
{
return theProperty.GetValue(oRecord, null).ToString();
}
}
catch (Exception theException)
{
// Do something with the exception
return string.empty;
}
}
Update
To process all of the properties, you can use code similar to this (note that this does not take into account IEnumerable implementors, but that should be fairly straightforward):
public static void GetAllProperties(object oRecord)
{
System.Type oType = null;
try
{
oType = oRecord.GetType();
PropertyInfo[] cProperties;
cProperties = oType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo theProperty in cProperties)
{
if (theProperty.PropertyType.IsClass)
{
GetAllProperties(theProperty.GetValue(oRecord, null));
}
else
{
// use theProperty.GetValue(oRecord, null).ToString();
}
}
}
catch (Exception theException)
{
// Do something with the exception
}
}

how to get all primitive type of an object

I wanna have all properties of an object which have primitive type, and if the object has a relation to another class , I wanna have the primitive properties of this another class too
the problem is if entity A has entity B and B has A, what can I do
in simple case by using reflection I can get first level Primitive properties but, I cant go into entity B and again get primitive properties of A,, a loop would be created,, what is ur offer?
public class A
{
public string Name{get;set;}
public B B{get;set;}
}
public class B
{
public string Category{get;set;}
public A A{get;set;}
}
You could keep a track of visited types to avoid recursion:
public class A
{
public string Name { get; set; }
public B B { get; set; }
}
public class B
{
public string Category { get; set; }
public A A { get; set; }
}
class Program
{
static void Main()
{
var result = Visit(typeof(A));
foreach (var item in result)
{
Console.WriteLine(item.Name);
}
}
public static IEnumerable<PropertyInfo> Visit(Type t)
{
var visitedTypes = new HashSet<Type>();
var result = new List<PropertyInfo>();
InternalVisit(t, visitedTypes, result);
return result;
}
private void InternalVisit(Type t, HashSet<Type> visitedTypes, IList<PropertyInfo> result)
{
if (visitedTypes.Contains(t))
{
return;
}
if (!IsPrimitive(t))
{
visitedTypes.Add(t);
foreach (var property in t.GetProperties())
{
if (IsPrimitive(property.PropertyType))
{
result.Add(property);
}
InternalVisit(property.PropertyType, visitedTypes, result);
}
}
}
private static bool IsPrimitive(Type t)
{
// TODO: put any type here that you consider as primitive as I didn't
// quite understand what your definition of primitive type is
return new[] {
typeof(string),
typeof(char),
typeof(byte),
typeof(sbyte),
typeof(ushort),
typeof(short),
typeof(uint),
typeof(int),
typeof(ulong),
typeof(long),
typeof(float),
typeof(double),
typeof(decimal),
typeof(DateTime),
}.Contains(t);
}
}
I am bored at work waiting for a build, have fun with your homework ;)
namespace Scratchpad
{
public static class TypeExtractor
{
public static IEnumerable<Type> ExtractTypes(this Type owner, HashSet<Type> visited = null)
{
if (visited == null)
visited = new HashSet<Type>();
if (visited.Contains(owner))
return new Type[0];
visited.Add(owner);
switch (Type.GetTypeCode(owner))
{
case TypeCode.Object:
break;
case TypeCode.Empty:
return new Type[0];
default:
return new[] {owner};
}
return
owner.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.FlattenHierarchy)
.SelectMany(x => x.ExtractTypes(visited)).Union(new[] {owner}).Distinct();
}
public static IEnumerable<Type> ExtractTypes(this MemberInfo member, HashSet<Type> visited)
{
switch (member.MemberType)
{
case MemberTypes.Property:
return ((PropertyInfo) member).PropertyType.ExtractTypes(visited);
break;
case MemberTypes.Field:
return ((FieldInfo) member).FieldType.ExtractTypes(visited);
default:
return new Type[0];
}
}
}
public class A
{
public string Name { get; set; }
public B B { get; set; }
}
public class B
{
public string Category { get; set; }
public A A { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
var q = typeof (A).ExtractTypes();
foreach (var type in q)
{
Console.Out.WriteLine(type.Name);
}
}
}
}
I would made as follows:
void Traverse(Type type, ISet<Type> marks, ICollection<PropertyInfo> result)
{
if (marks.Contains(type)) return; else marks.Add(type);
foreach (var propertyInfo in type.GetProperties())
if (propertyInfo.PropertyType.IsPrimitive) result.Add(propertyInfo);
else Traverse(propertyInfo.PropertyType, marks, result);
}
and
var props = new List<PropertyInfo>();
Traverse(yourRootType, new HashSet<Type>(), props);
You need to keep track of types you've already checked.
public static List<PropertyInfo> ProcessType(Type type)
{
return ProcessType(type, new List<Type>());
}
public static List<PropertyInfo> ProcessType(Type type, List<Type> processedTypes)
{
// Keep track of results
var result = new List<PropertyInfo>();
// Iterate properties of the type
foreach (var property in type.GetProperties())
{
var propertyType = property.PropertyType;
// If the property has a primitive type
if (propertyType.IsPrimitive)
{
// add it to the results
result.Add(property);
}
// If the property has a non-primitive type
// and it has not been processed yet
else if (!processedTypes.Contains(propertyType))
{
// Mark the property's type as already processed
processedTypes.Add(propertyType);
// Recursively processproperties of the property's type
result.AddRange(ProcessType(propertyType, processedTypes));
}
}
return result;
}

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