在我的 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
要广泛得多,使得这种方法不切实际。
我希望这可以通过反思来实现,因为性能在这里并不重要。但我不知道该怎么做。有人可以建议吗?
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);