tags:

views:

1074

answers:

5

Hey guys I'm trying to do do the following.

GetString(
    inputString,
    ref Client.WorkPhone)

...

private void GetString(string in, ref string out)
{
    if (!string.IsNullOrEmpty(in))
    {
        out = in;
    }
}

This is giving me a compile error, I think its pretty clear what I'm trying to achieve basically I want GetString to copy the contents of an input string "Input String" to the WorkPhone property of Client.

Is it possible to pass a property by reference?

Thanks in advance.

+5  A: 

cannot pass properties by reference

Steven A. Lowe
+1  A: 

This is not possible. You could say

Client.WorkPhone = GetString(inputString, Client.WorkPhone);

where WorkPhone is a writeable string property and the definition of GetString is changed to

private string GetString(string in, string current) { 
    if (!string.IsNullOrEmpty(in)) {
        return in;
    }
    return current;
}

This will have the same semantics that you seem to be trying for.

This isn't possible because a property is really a pair of methods in disguise. Each property makes available getters and setters that are accessible via field-like syntax. When you attempt to call GetString as you've proposed, what you're passing in is a value and not a variable. The value that you are passing in is that returned from the getter get_WorkPhone.

Jason
+2  A: 

This is covered in section 7.4.1 of the C# language spec. Only a variable-reference can be passed as a ref or out parameter in an argument list. A property does not qualify as a variable reference and hence cannot be used.

JaredPar
+5  A: 

Properties cannot be passed by reference. Here are a few ways you could work around this limitation.

1. Return Value

string GetString(string input, string output)
{
    if (!string.IsNullOrEmpty(input))
    {
        return input;
    }
    return output;
}

void Main()
{
    var person = new Person();
    person.Name = GetString("test", person.Name);
    Debug.Assert(person.Name == "test");
}

2. Delegates

void GetString(string input, Func<string> getOutput, Action<string> setOutput)
{
    if (!string.IsNullOrEmpty(input))
    {
        setOutput(input);
    }
}

void Main()
{
    var person = new Person();
    GetString("test", () => person.Name, value => person.Name = value);
    Debug.Assert(person.Name == "test");
}

3. Linq Expressions

void GetString<T>(string input, T outObj, Expression<Func<T, string>> outExpr)
{
    if (!string.IsNullOrEmpty(input))
    {
        var expr = (MemberExpression) outExpr.Body;
        var prop = (PropertyInfo) expr.Member;
        prop.SetValue(outObj, input, null);
    }
}

void Main()
{
    var person = new Person();
    GetString("test", person, x => x.Name);
    Debug.Assert(person.Name == "test");
}
Nathan Baulch
A: 

What you could try to do is create an object to hold the property value. That way you could pass the object and still have access to the property inside.

Anthony Reese