Zoinky
Zoinky

Reputation: 4999

Passing a property by reference into a method (same name, different classes)

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

I cannot have my 2 classes inherit from a baseclass that has Address property (long story)

I was under the impression that when passing objects into methods they are by reference and my obj1.Address will have a new one and not be null if i am passing that property into a method.

If my assumption is wrong and it seems to be about object not being passed by reference in this instance.

How can i have a generic method that I can update a property that is the same across all my objects (I know I can return a new address object but I prefer to be passed in instead of returning)

Can this also be done by passing T<>?

UPDATE - Actual Code

Calling the methods

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

Upvotes: 0

Views: 152

Answers (2)

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

Usual options:

  • shared base class (if you can change code and class hierarchy)
  • shared interface (if you can can change code, but no class hierarchy)
  • pass lambdas for getter/setter
  • use reflection and set by name

Since it sounds like you can't change the source lambda option may be the easiest. Following is option to "set" (when you replace whole object):

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

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

If you need to set properties of such object instead of replacing - pass get delegate:

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

Or use both. You can even combine them into helper class so it look close to properties (check out adapter pattern.

Note: generics not going to help you unless you can add common interface (but in that case you probably don't need generics at all).

Upvotes: 2

David Arno
David Arno

Reputation: 43254

If UpdateAddress only returns an address then change it to:

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


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

Passing by reference and manipulating the contents of a parameter is a code smell. Write methods that return values and set the property that way.

Upvotes: 0

Related Questions