【问题标题】:Passing a property by reference into a method (same name, different classes)通过引用将属性传递给方法(同名,不同类)
【发布时间】:2015-09-28 15:35:35
【问题描述】:
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 为空

我不能让我的 2 个类从具有 Address 属性的基类继承(长话短说)

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

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

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

通过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;
    }

【问题讨论】:

  • 两个类可以从同一个接口实现吗?参考 Jon yoda.arachsys.com/csharp/parameters.html 的这篇文章,对参数传递有一个很好的了解。
  • “我的印象是,当将对象传递给方法时,它们是通过引用进行的”。不,他们不是。根本不传递对象。引用按值传递。见pobox.com/~skeet/csharp/parameters.html
  • @SriramSakthivel 不幸的是他们不能,这些是实体框架类,而 Address 是一个共享表,它成为每个实体的属性
  • 几乎与 Jon Skeet 使用 lambdas 删除的答案重复...stackoverflow.com/questions/1178574/…

标签: c#


【解决方案1】:

常用选项:

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

因为听起来您无法更改源 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

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

【讨论】:

  • @Zoinky 我假设您只想更改“地址”的 一些 属性? (见更新)......不知道“为什么要返回一个int”。涉及到。
  • 我想要做的只是如果记录是新的,那么他们要么选择了一个供应商(供应商正在填写),要么其他属性来自模型,例如名称地址等。但是如果 t他的记录是一个更新,然后确保从字段中更新地址组件。总而言之,我需要重新评估我设置供应商的策略,因为代码变得令人困惑
【解决方案2】:

如果UpdateAddress 只返回一个地址,则将其更改为:

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


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

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

【讨论】:

  • 该方法已经返回一个 int (示例中未显示),但我想我可以更改它以使返回更通用。我试图避免返回对象,无论如何可能都必须这样做
  • @Zoinky,那个 int 的目的是什么?您试图通过“后门”返回地址,将其视为参考。
猜你喜欢
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多