将对象作为 ref 参数传递给泛型方法

passing object as a ref parameter to generic method

我已经创建了一个泛型方法,我想通过引用这个方法来传递一个对象来填充一些属性。它编译并运行没有问题,但是对象没有被填充。

我的通用方法

public static void SplitAddress<T>(ref T ob, string addressToSplit) where T : Address
    {
        //ptr : Postcode, Town, Region
        var ptr = addressToSplit.Split(new char[] { '-' }, 2, StringSplitOptions.RemoveEmptyEntries).ToList();
        var pt = ptr[0].Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries).ToList();

        if (ptr.Count == 2)
        {
            ob.Region = ptr[1];
        }

        for (int x = 0; x < pt.Count; x++)
        {
            switch (x)
            {
                case 0:
                    {
                        ob.PostCode = pt[x];
                        break;
                    }
                case 1:
                    {
                        ob.Town = pt[x];
                        break;
                    }
            }
        }
    }

我要传递的对象

class Merchant : Address
{
    public int MeId { get; set; }
    public int HoId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public string PostCode { get; set; }
    public string Town { get; set; }
    public string Region { get; set; }
    public string VatNr { get; set; }
    public string TRSshopId { get; set; }

}

地址class

abstract class Address
{
    public string PostCode;
    public string Town { get; set; }
    public string Region { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Adrress { get; set; }
}

方法调用

Methods.SplitAddress<Merchant>(ref me, row.Cells[i].Text);

我可以为两种不同的对象类型创建两个重载方法,但它们会重复相同的代码,这是我想避免的。 它看起来很奇怪,但是例如 "Postcode" 正在被填充,但是当我将鼠标悬停在 "ob" 上时,属性 仍然是空的。

编辑

正如@Lee 敏锐地注意到的那样,您隐藏 Address 的属性到Member。由于您的泛型方法被限制为 Address 类型的成员,您的代码实际上是在更改隐藏的 Address class 的属性,而不是 Merchant class,所以如果您有 Merchant 类型的变量,您将看不到这些更改。如果将 Member 转换为 Address,您会看到这些值。只需从 Merchant 中删除这些属性就可以了。

p.s。 Member 继承 形式 Address 似乎是错误的 - 成员 有一个 地址,它 不是一个地址。更好的设计是:

class Merchant
{
    public int MeId { get; set; }
    public int HoId { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
    public string VatNr { get; set; }
    public string TRSshopId { get; set; }

}

原答案

I want to pass an object by a reference to this method to populate few properties

由于 Address 是 class,您 不需要 使用 ref。引用类型的参数将包含对与传入变量相同的对象的 reference,因此您可以更改该对象的属性值,调用方法将看到变化。 ref 让你做的主要事情是更改对 different 对象的引用,你没有这样做,所以使用 ref 不会改变你的内容正在努力做。

我建议你在调试器中 运行 它以确保你的 if 块按照你期望的方式执行。 (例如 ptr.Count == 2 是真的吗?它可以大于 2 吗?)

你的整个 for 块也可以减少到:

if(pt.Count > 0)  ob.PostCode = pt[0];
if(pt.Count > 1)  ob.Town = pt[1];