gpt4 book ai didi

c# - 使用反射映射相似对象 : Object does not match target type

转载 作者:行者123 更新时间:2023-11-30 20:26:09 24 4
gpt4 key购买 nike

尽管查看了多个 SO 帖子和我能想到的任何其他内容,但我在这里完全不知所措。

我的目标是制作一个非常非常简单的映射器。我基本上可以在某些单元测试中用作工具。它不需要复杂或任何东西——只需将一个对象的高级原始值和字符串值映射到另一个对象。所以基本算法是:

  1. TFrom 获取所有属性>
  2. TTo 获取所有属性>
  3. 获取两者中的所有属性,按名称匹配。
    • 我知道这可能是一个错误,因为它们可能具有相同的名称但类型不同,但让我们把它放在一边。这不是我在这里遇到的问题——类之间的属性和类型匹配。
  4. 创建我们可以复制到的 TTo 实例。
  5. 对于对象之间映射的每个属性:
    1. 获取from对象的值
    2. 将值转换为属性的类型
    3. 设置对象的值

问题是,无论我做什么,无论属性的类型是什么(例如 intstring),我都会得到以下信息:

Object does not match the target type.

这是我使用的代码:

public TTo Map<TFrom, TTo>(TFrom from)
{
if (from == null) return default;

var fromProps = GetProperties(typeof(TFrom));
var toProps = GetProperties(typeof(TTo));

// Props that can be mapped from one to the other
var propsToCopy = fromProps.Intersect(toProps, new PropertyComparer()).ToList();

var returnObject = (TTo)Activator.CreateInstance(typeof(TTo));

foreach (var prop in propsToCopy)
{
// Copy the values
var fromValue = prop.GetValue(from, null);
var convertedValue = Convert.ChangeType(fromValue, prop.PropertyType);
prop.SetValue(returnObject, convertedValue, null);
}

return returnObject;
}

public PropertyInfo[] GetProperties(Type objectType)
{
var allProps = objectType.GetProperties(
BindingFlags.Public | BindingFlags.Instance);

return allProps.Where(p => p.PropertyType.IsPrimitive ||
p.PropertyType == typeof(string)).ToArray();
}

private class PropertyComparer : IEqualityComparer<PropertyInfo>
{
public bool Equals(PropertyInfo x, PropertyInfo y)
{
return x.Name.Equals(y.Name);
}

public int GetHashCode(PropertyInfo obj)
{
return obj.Name.GetHashCode();
}
}

下面是一个我称之为示例类的方法示例:

public class Foo 
{
public string StringProp { get; set; }
public int IntProp { get; set; }
}

public class FooOther
{
public string StringProp { get; set; }
public int IntProp { get; set; }
}

var foo = new Foo { IntProp = 1, StringProp = "foo" };
var mappedFoo = Map<Foo, FooOther>(foo);

我从 Visual Studio 中得到的唯一提示是来自监 window 口:如果属性类型是 string,监 window 口会报告 convertedValue 的类型> 作为对象。如果属性类型是 int,则监 window 口报告 object {int}

最佳答案

您正在使用的 PropertyInfo 仍然与它所代表的属性所属的类型相关联,因此您无法使用它来设置另一种类型的对象的值,而不会出现您遇到的错误。

这是一个简短的行为示例:

public class A {
public string Id {get;set;}
}
public class B {
public string Id {get;set;}
}

void Main()
{
var test = new A() { Id = "Test"};
var prop = test.GetType().GetProperty("Id");

var b = (B)Activator.CreateInstance(typeof(B));

var fromValue = prop.GetValue(test);
var converted = Convert.ChangeType(fromValue, prop.PropertyType);
prop.SetValue(b, converted, null); // Exception
}

如果您将 PropertyInfo 视为 A 的成员,这是有道理的。要解决此问题,您需要获取特定于您的类型的属性信息。我可以用以下内容修复我的示例:

var propTo = typeof(B).GetProperty(prop.Name);
propTo.SetValue(b, converted, null);
Console.WriteLine(b.Id); // Output: Test

综上所述,如果您将 foreach 的内容更改为以下内容,您应该清楚:

foreach (var prop in propsToCopy)
{
// Copy the values
var fromValue = prop.GetValue(from, null);
var convertedValue = Convert.ChangeType(fromValue, prop.PropertyType);
var propTo = typeof(TTO).GetProperty(prop.Name);
propTo.SetValue(returnObject, convertedValue, null);
}

关于c# - 使用反射映射相似对象 : Object does not match target type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50402739/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com