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

时间:2015-08-27 16:32:14

标签: c# object generics pass-by-reference ref

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

我的通用方法

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

}

地址类

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);

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

1 个答案:

答案 0 :(得分:4)

修改

正如@Lee敏锐地注意到的那样,您隐藏 AddressMember的属性。由于您的泛型方法被约束为Address类型的成员,因此您的代码实际上正在更改隐藏的Address类的属性,而不是Merchant类的属性,因此您如果您有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; }

}

原始答案

  

我想通过对此方法的引用传递一个对象来填充一些属性

由于Address是一个类,因此 不需要使用ref。引用类型的参数将包含与传入的变量相同的对象的引用,因此您可以更改该对象的属性值,并且调用方法将看到更改。允许您执行的主要操作是更改对不同对象的引用,而您没有这样做,因此使用ref不会更改您尝试的内容做。

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

此外,您的整个2广告块可以缩减为:

for