C# 使用反射c映射两个对象#
我正在创建一个函数来循环对象及其子对象 但当我尝试从原始对象映射到新对象时,出现了一些问题,下面是代码:C# 使用反射c映射两个对象#,c#,reflection,C#,Reflection,我正在创建一个函数来循环对象及其子对象 但当我尝试从原始对象映射到新对象时,出现了一些问题,下面是代码: public static bool MatchObjectField<T>(this T obj, string objectRoute, string value) { try { var objectroutelist = objectRoute.Split('.'); var objroute = objectroutel
public static bool MatchObjectField<T>(this T obj, string objectRoute, string value)
{
try
{
var objectroutelist = objectRoute.Split('.');
var objroute = objectroutelist.First();
var childproperty = typeof(T).GetProperty(objroute);
if (objectroutelist.Count() == 1)
{
if (childproperty.GetValue(obj).ToString().Trim() == value)
{
return true;
}
return false;
}
else
{
var instance = Activator.CreateInstance(childproperty.PropertyType);
//childproperty.SetValue(obj, instance, null);
//childproperty.SetValue(instance, obj, null);
instance.MapValues(childproperty);
instance.MatchObjectField(string.Join(".", objectroutelist.Skip(1)), value);
}
}
catch (Exception e)
{
return false;
}
return false;
}
TL;博士:退后一步。分别描述每个方法的职责,并以这种方式为它们编写测试。从“最低级别”的方法开始,然后逐步提高。这将使我们更容易发现问题所在
这里有很多问题。首先看这两行代码:
var instance = Activator.CreateInstance(childproperty.PropertyType);
instance.MapValues(childproperty);
Activator.CreateInstance
的返回类型是object
,因此这实际上是:
var instance = Activator.CreateInstance(childproperty.PropertyType);
instance.MapValues<object>(childproperty);
该参数是一个值参数,因此在方法末尾指定它是没有意义的
您应该决定MapValues
的用途:
- 是创建一个实例并填充它,然后返回它吗
- 是否接受现有实例并填充该实例
最后,还有一个问题是这些值来自哪里。您当前正在调用
PropertyInfo
上的GetPropertiesWithValues
——这不会达到我认为您期望的效果。您需要提供源对象本身,否则就无法从中获取值。我在这篇文章中找到了我需要做的事情:获取嵌套对象是我假装要做的一种简单方法
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
{
var prop = src.GetType().GetProperty(propName);
return prop != null ? prop.GetValue(src, null) : null;
}
}
public static bool MatchObjectField<T>(this T obj, string objectRoute, string value)
{
try
{
var propvalue = GetPropertyValue(obj, objectRoute);
return ( propvalue.ToString().Trim() == value.Trim());
}
catch (Exception) {
throw;
}
}
公共静态对象GetPropertyValue(对象src,字符串propName)
{
如果(src==null)抛出新的ArgumentException(“值不能为null。”,“src”);
如果(propName==null)抛出新的ArgumentException(“值不能为null。”,“propName”);
if(propName.Contains(“.”)//嵌套的复杂类型
{
var temp=propName.Split(新字符[]{.'},2);
返回GetPropertyValue(GetPropertyValue(src,temp[0]),temp[1]);
}
其他的
{
var prop=src.GetType().GetProperty(propName);
return prop!=null?prop.GetValue(src,null):null;
}
}
公共静态布尔MatchObjectField(此T对象、字符串objectRoute、字符串值)
{
尝试
{
var propvalue=GetPropertyValue(obj,objectRoute);
返回(propvalue.ToString().Trim()==value.Trim());
}
捕获(例外){
投掷;
}
}
GetProperties With Value defined在哪里?你为什么不使用AutoMapper?@evdzhan Mustafa我添加了函数,但基本上是返回一个字典
@LasseVågsætherKarlsen它没有安装在应用程序中,我只使用了几次,但老实说,当我第一次想到这个方法时,我并没有料到会出现这种错误。你认为automapper可以解决这个问题吗?据我所知,你想在特定的属性结构中匹配特定的属性值,对吗?那你为什么要在每个递归步骤上创建一个实例,做各种各样的事情,而不是递归地搜索特定的属性,然后进行值匹配呢?谢谢你的提示,一切都很清楚,我把一切都复杂化了;我看到了这一切,这足以满足我的需要。谢谢
var instance = Activator.CreateInstance(childproperty.PropertyType);
instance.MapValues<object>(childproperty);
destination = (T)(object)instance;
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
{
var prop = src.GetType().GetProperty(propName);
return prop != null ? prop.GetValue(src, null) : null;
}
}
public static bool MatchObjectField<T>(this T obj, string objectRoute, string value)
{
try
{
var propvalue = GetPropertyValue(obj, objectRoute);
return ( propvalue.ToString().Trim() == value.Trim());
}
catch (Exception) {
throw;
}
}