简体   繁体   中英

passing object as a ref parameter to generic method

I have created a generic method, and I want to pass an object by a reference to this method to populate few properties. It compiles, and runs without problems, but the object is not being populated.

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

Object i want to pass

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

}

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

method invocation

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

I could create two overloaded methods, for two different object types, but they will repeat the same code, which I want to avoid. It look very odd, but for example "Postcode" is being populated, but when I hover the mouse on "ob", the property is still empty.

EDIT

As @Lee astutely noticed, you are hiding the properties of Address in Member . Since your generic method is constrained to members of type Address , your code is actually changing the properties of the Address class that are hidden, not the properties of the Merchant class, so you are not seeing those changes if you have a variable of type Merchant . You would see the values if you cast the Member to an Address . Just remove those properties from Merchant and you should be fine.

ps Member inheriting form Address seems wrong - a member has an address, it is not an address. a better design would be:

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

}

Original Answer

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

Since Address is a class, you don't need to use ref . A parameter of a reference types will contain a reference to the same object as the variable that's passed in, so you can change the values of the properties of that object and the calling method will see the changes. The main thing ref lets you do is change the reference to a different object, which you aren't doing, so using ref won't change what you are trying to do.

I suggest you run it in the debugger to make sure your if blocks are getting executed the way you expect them to. (eg is ptr.Count == 2 true? could it be greater then 2 ?)

Also your entire for block can be reduced to:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM