C#类转换为类

时间:2015-12-10 16:04:01

标签: c#

假设我有两对具有完全相同属性的不同类。

public class Class1
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
}

public class Class2
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
}

是否可以创建一个方法,将任何object作为参数,并返回object我传入Class1的地方,然后返回Class2或反之亦然知道什么课程将被传递?我们可以假设这两个类将共享完全相同的属性。我们需要在调用方法时定义我们想要返回的Type

4 个答案:

答案 0 :(得分:6)

在编译时不知道类型的唯一方法是使用反射:

  • 获取每种类型的所有属性的列表
  • 按名称查找匹配的属性
  • 每个属性:
    • 从对象1获取值
    • 设置对象2的值(必要时进行转换)

像AutoMapper这样的工具开箱即用,但几乎总是在从一种类型映射到另一种类型时需要某种自定义配置。

如果您有两种类型具有完全相同的属性和类型,那么您可能需要公共属性的基本类型?

答案 1 :(得分:1)

假设您可以修改代码以使所有类实现公共接口:

public interface SomeInterface
{
    int IntValue { get; set; }
    string StringValue { get; set; }
}

public class Class1 : SomeInterface
{
    public int IntValue { get; set; }
    public string StringValue { get; set; }
}

public class Class2 : SomeInterface etc

然后可以创建一个简单的方法来从一个方法转换为另一个方法:

public T1 Convert<T1, T2>(T2 source) where T1 : SomeInterface, T2 : SomeInterface
{
    return new T1
    {
        IntValue = source.IntValue,
        StringValue = source.StringValue
    };
}

然后按以下方式使用它:

var x = new Class1 { IntValue = 1, StringValue = "someText" };
...
Class2 y = Convert(x);

然而,更实际的解决方案是删除多个类,所有类都具有相同的结构,并用普通类替换它们。

答案 2 :(得分:1)

是的,可以使用反射并迭代每个属性。唯一的问题是当你的类隐藏无参数构造函数时,然后你可以通过参数传递它而不是在转换器中创建这个对象。

下面的解决方案并不要求两个类都包含相同的属性。

using System;
using System.Linq;

namespace Utils
{
    public static class TypeConverter
    {
        public static TDestination Convert<TSource, TDestination>(TSource source)
        {
            var destination = Activator.CreateInstance<TDestination>();
            var destProperties = destination.GetType()
                                            .GetProperties()
                                            .ToDictionary(x => x.Name);

            foreach (var prop in source.GetType().GetProperties())
            {
                if (destProperties.ContainsKey(prop.Name))
                {
                    destProperties[prop.Name].SetValue(destination, prop.GetValue(source));
                }
            }

            return destination;
        }
    }
}

用法:

var c1 = new Class1() { IntValue = 1, StringValue = "aaaa" };
var c2 = TypeConverter.Convert<Class1, Class2>(c1);

答案 3 :(得分:0)

如果你这样做,你只需要使用System.Reflection和使用Dictionaries来映射数据。

public T ConvertClass<T>(X objectModel) 
{
    Dictionary<string,string> columnMapping = new Dictionary<string,string>
    string valueTempplete = "'{value}'"
    foreach(var prop in objectModel.GetType().GetProperties(BindingFlags)) 
    {
        var propertyName = prop.Name;
        var value = objectModel.GetType().GetProperty(propertName).GetValue(objectModel, null).ToString();
        columnMapping.Add(propertyName, valueTemplete.Replace("{value}",value))
    }
}

使用值模板的原因是每次进入循环时都不会创建字符串的新实例。您将不得不想办法将字典数据映射到T对象。在弄清楚之后,您可以将要转换的类传递到&lt;&gt;,并将要转换的对象传入参数。我知道这不是一个完整的答案,但应该给你一个良好的开端。