Search code examples
c#propertiespass-by-reference

Passing properties by reference in C#


I'm trying to do do the following:

GetString(
    inputString,
    ref Client.WorkPhone)

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

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 to the WorkPhone property of Client.

Is it possible to pass a property by reference?


Solution

  • Properties cannot be passed by reference. Here are a few ways you can 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. Delegate

    void GetString(string input, Action<string> setOutput)
    {
        if (!string.IsNullOrEmpty(input))
        {
            setOutput(input);
        }
    }
    
    void Main()
    {
        var person = new Person();
        GetString("test", value => person.Name = value);
        Debug.Assert(person.Name == "test");
    }
    

    3. LINQ Expression

    void GetString<T>(string input, T target, Expression<Func<T, string>> outExpr)
    {
        if (!string.IsNullOrEmpty(input))
        {
            var expr = (MemberExpression) outExpr.Body;
            var prop = (PropertyInfo) expr.Member;
            prop.SetValue(target, input, null);
        }
    }
    
    void Main()
    {
        var person = new Person();
        GetString("test", person, x => x.Name);
        Debug.Assert(person.Name == "test");
    }
    

    4. Reflection

    void GetString(string input, object target, string propertyName)
    {
        if (!string.IsNullOrEmpty(input))
        {
            var prop = target.GetType().GetProperty(propertyName);
            prop.SetValue(target, input);
        }
    }
    
    void Main()
    {
        var person = new Person();
        GetString("test", person, nameof(Person.Name));
        Debug.Assert(person.Name == "test");
    }