在另一个对象中设置类似的对象属性

Posted

技术标签:

【中文标题】在另一个对象中设置类似的对象属性【英文标题】:Set similar object properties in another object 【发布时间】:2009-06-11 16:05:26 【问题描述】:

我有两个对象,它们包含一些完全相同的属性(相同的名称、类型)。我想要做的是用另一个对象的属性填充一个对象的相同属性。我正在尝试在代码中执行此操作,但它不起作用。未设置 Bin 对象的属性。

class Basket
    public Basket(int itemId, int itemGroup)
        ItemId=itemId;
        ItemGroup=itemGroup;
    
    private int _itemId;
    private int _itemGroup;
    public int ItemId getreturn _itemId; set_itemId = value;
    public int ItemGroup getreturn _itemGroup; set_itemGroup = value;


struct Bin
    public string Name;
    private int _itemId;
    private int _itemGroup;
    public int ItemId getreturn _itemId; set_itemId = value;
    public int ItemGroup getreturn _itemGroup; set_itemGroup = value;
    public bool IsEmpty;


Basket basket = new Basket(1,1);
Bin bin = new Bin();

PropertyInfo[] basketPI = basket.GetType().GetProperties();
PropertyInfo[] binPI = bin.GetType().GetProperties();

foreach(PropertyInfo biPI in binPI)
    foreach(PropertyInfo baPI in basketPI)
        if(baPI.Name==biPI.Name)
            biPI.SetValue(bin,baPI.GetValue(basket,null),null));
        
    

我试图摆脱简单的做事:

object1.ItemId = object2.ItemId;
object1.ItemGroup = object2.ItemGroup;

我也想知道是否有更优雅的方法来做到这一点?

编辑:我缩短了课程;意味着在那里有get/set。

编辑:从对象更改为结构。出于某种原因,它不喜欢在我这样做时设置结构的属性。

【问题讨论】:

由于您已编辑为代码,我看不出它无法正常工作的任何明显原因。您是否使用调试器单步执行了代码?它是否返回两个对象的完整属性列表?名称是否完全相同?它是否曾经到达 SetValue 代码行? 哎呀,我的错。我以为它们都是对象,但一个是结构,一个是对象。难怪 GetValue/SetValue 不起作用! 【参考方案1】:

您可以使用AutoMapper,它允许您配置地图,以便将一个对象转换为另一个对象。

博文:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx

以下是 AutoMapper 的 Projection 页面的示例

public class CalendarEvent

    public DateTime EventDate  get; set; 
    public string Title  get; set; 


public class CalendarEventForm

    public DateTime EventDate  get; set; 
    public int EventHour  get; set; 
    public int EventMinute  get; set; 
    public string Title  get; set; 


// Model
var calendarEvent = new CalendarEvent

    EventDate = new DateTime(2008, 12, 15, 20, 30, 0),
    Title = "Company Holiday Party"
;

// Configure AutoMapper
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
    .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))
    .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour))
    .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));
// Perform mapping

CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);
form.EventDate.ShouldEqual(new DateTime(2008, 12, 15));
form.EventHour.ShouldEqual(20);
form.EventMinute.ShouldEqual(30);
form.Title.ShouldEqual("Company Holiday Party");

【讨论】:

【参考方案2】:

您在类中定义的内容是字段而不是属性,因此 GetProperties() 方法不会列出它们。

尝试将它们更改为(例如):

public int ItemId  get; set; 

假设您使用 .NET 3.0 或更高版本,否则:

private int _itemId;
public int ItemId

    get  return _itemId; 
    set  _itemId = value; 

我质疑你想要做什么?继承可能是使其更优雅的一种选择 - 将共享属性分解为基类。但是如果只有这两个属性,那么直接复制值的代码有什么问题呢?

【讨论】:

这只是一个简单的例子,我真正使用的对象有很多属性,我希望让代码处理它而不是全部写出来。【参考方案3】:

我会考虑创建一个对象属性,然后进行克隆以复制值。整个方法似乎是一种 hack。如果属性有不同的类型怎么办?

您还可以使用和接口来定义 IAdressSupport 以查找支持的项目。

PersonB.Address=directcast(PersonA.Address.Clone, Address)

【讨论】:

以上是关于在另一个对象中设置类似的对象属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 presentViewController 方法在另一个 VC 中设置属性

使用 webflux 在另一个中设置一个单声道

有没有办法只在 C# 中设置一次属性

有没有办法只在 C# 中设置一次属性

如何在另一个模块中设置全局变量?

在python中从字典中设置属性