通过值转换器将属性从一个泛型类复制到另一个泛型类

问题描述 投票:0回答:1

在我的 C# 应用程序中,我有一个类充当数据结构来保存各种类别,其中可能保存子类别或类别列表,最终保存保存值和其他关联数据的数据属性。

DataStructure
类是通用的,因为它直接在应用程序中的多个位置使用或作为扩展的基类,并且
DataProperty
中的值类型在每个用例中都会有所不同。在某些时候,我需要将值从一种类型的
DataStructure
实例传输到另一种类型的
DataStructure
实例。例如,如果第一个
DataStructure
的类型为
string
,第二个的类型为
double
,则转换器将通过一些自定义逻辑转换每个
DataProperty
的值。任何类别列表也需要填写在第二个
DataStructure
中,以便所有内容都与第一个
DataStructure
匹配。

所以本质上我需要制作

DataStructure
实例的副本,但使用另一种类型,使用自定义转换器转换值。如果第二个数据结构是派生自
DataStructure
的类的实例,这也需要起作用。这是显示设置的代码的简化版本:

static void Main(string[] args)
{
    DataStructure<string> dataStructureStr = new();
    FillData(dataStructureStr); //Fills lists of categories, writes some string type values into DataProperty properties
    DataStructure<double> dataStructureDbl = new();
    ConvertAndCopyData(dataStructureStr, dataStructureDbl); //Transfers values of all properties from one DataStructure to another using a converter
}

public interface ICategory
{
    //...
}

public abstract class Category : ICategory
{
    //...
}

public class DataProperty<T>
{
    public T Value { get; set; }
    //...
}

public class DataStructure<T> 
{
    public EnvironmentData Environment { get; init; } = new();

    public class EnvironmentData : Category
    {
        public LightData Light { get; init; } = new();
        public List<Force> Forces { get; init; } = new();

        public class LightData : Category
        {
            public LightPositionData LightPosition { get; init; } = new();
            public DataProperty<T> Intensity { get; init; } = new();

            public class LightPositionData : Category
            {
                public DataProperty<List<T>> OriginCoordsXYZ { get; init; } = new();
                public DataProperty<List<T>> TargetCoordsXYZ { get; init; } = new();
            }
        }
        public class Force : Category
        {
            public DataProperty<T> Magnitude { get; init; } = new();
        }
    }
    //...
}

虽然

ConvertAndCopyData
函数可以通过显式寻址每个类别、子类别和数据属性来实现,但它需要我再次键入整个结构,并且如果我更改原始内容中的任何内容,则需要手动维护此函数
 DataStructure
。我的实际应用中的
DataStructure
要广泛得多,使得这种方法不切实际。

我希望这可以通过反思来实现,因为性能在这里并不重要。但我不知道该怎么做。有人可以建议吗?

c# generics data-manipulation
1个回答
0
投票

您可以使用

AutoMapper
将一个对象转换为另一个对象。您必须为具有泛型类型的类创建映射,请参阅AutoMapper - 功能 - 开放泛型。映射可能如下所示:

var config = new MapperConfiguration(cfg => {
    cfg.CreateMap(typeof(DataStructure<>), typeof(DataStructure<>));
    cfg.CreateMap(typeof(DataStructure<>.EnvironmentData), typeof(DataStructure<>.EnvironmentData));
    cfg.CreateMap(typeof(DataStructure<>.EnvironmentData.LightData), typeof(DataStructure<>.EnvironmentData.LightData));
    cfg.CreateMap(typeof(DataStructure<>.EnvironmentData.LightData.LightPositionData), typeof(DataStructure<>.EnvironmentData.LightData.LightPositionData));
    cfg.CreateMap(typeof(DataProperty<>), typeof(DataProperty<>));
});

当您使用

config.CreateMapper();
创建映射器时,您可以使用以下方式映射您的对象:

mapper.Map(dataStructureStr, dataStructureDbl);
© www.soinside.com 2019 - 2024. All rights reserved.