通过引用将属性传递给方法(同名,不同类)

时间:2015-09-28 15:35:35

标签: c#

public class Address
{...}

public class Object1
{
   public Address Address {get;set;}
}

public class Object2
{
   public Address Address {get;set;}
}

public UpdateAddress(Address address)
{
   address = new Address();
}

//calling
var obj1 = new Object1();
UpdateAddress(obj1.Address);

// obj1.Address IS NULL

我不能让我的2个类继承自具有Address属性的基类(长篇故事)

我的印象是,当将对象传递给方法时,它们是通过引用而我的obj1.Address将有一个新的,如果我将该属性传递给方法,则不为null。

如果我的假设是错误的,那么在这种情况下似乎是关于对象没有通过引用传递。

我如何拥有一个通用方法,我可以更新所有对象中相同的属性(我知道我可以返回一个新的地址对象,但我更喜欢传入而不是返回)

这可以通过传递T<>?

来完成

更新 - 实际代码

调用方法

bool isVendorIdFromModel = UpdateVendor(entity.ExpenseVendor, entity.ExpenseVendorId, model, isNew, context);
if (isVendorIdFromModel)
{
    entity.ExpenseVendorId = model.VendorId;
}

private static bool UpdateVendor(ExpenseVendor vendor, int? entityVendorId, ExpenseBaseModel model, bool isNew, ELMSContext context)
    {
        if (model.VendorId.HasValue)
        {
            if (entityVendorId != model.VendorId)
            {
                return true;
            }
            UpdateVendorInfo(model, vendor);

        }
        else
        {
            if (isNew && !string.IsNullOrEmpty(model.VendorName))
            {
                vendor = new ExpenseVendor
                {
                    ...
                };
                context.ExpenseVendors.Add(vendor); 

            }
            if (vendor != null)
            {
                UpdateVendorInfo(model, vendor);
            }
        }
        return false;
    }
    private static void UpdateVendorInfo(ExpenseBaseModel model, ExpenseVendor vendor)
    {
        vendor.Name = model.VendorName;
        vendor.Address1 = model.Address1;
        vendor.Address2 = model.Address2;
        vendor.City = model.City;
        vendor.PostalCode = model.PostalCode?.Replace(" ", string.Empty);
        vendor.ProvinceId = model.ProvinceId;
    }

2 个答案:

答案 0 :(得分:2)

常用选项:

  • 共享基类(如果可以更改代码和类层次结构)
  • 共享接口(如果可以更改代码,但没有类层次结构)
  • 传递lambdas for getter / setter
  • 使用反射并按名称设置

因为听起来你无法改变源lambda选项可能是最简单的。以下是“设置”选项(当您替换整​​个对象时):

public void UpdateAddress(Action<Address> addressSetter)
{
   addressSetter(new Address());
}

//calling
var obj1 = new Object1();
UpdateAddress(address => obj1.Address = address);

如果您需要设置此类对象的属性而不是替换 - 传递get委托:

public void UpdateAddress(Func<Address> addressGetter)
{
   addressGetter().Street = "Dark alley";
}
UpdateAddress(address => obj1.Address);

或两者同时使用。您甚至可以将它们组合成帮助类,使其看起来与属性接近(请查看adapter pattern

注意:除非您可以添加通用界面,否则泛型不会帮助您(但在这种情况下,您可能根本不需要泛型)。

答案 1 :(得分:0)

如果UpdateAddress仅返回地址,请将其更改为:

public Address UpdateAddress()
{
    // set up address
    return address;
}


var obj1 = new Object1();
obj1.Address = UpdateAddress();

通过引用传递和操作参数的内容是代码气味。编写返回值的方法并以这种方式设置属性。