Generic functions and ref returns in C# 7.0

Is it possible to use the ref returns feature in C# 7.0 define a generic function that can do both comparison and update of a field in two instances of an Object? I am imagining something like this:

void UpdateIfChanged<TClass, TField>(TClass c1, TClass c2, Func<TClass, TField> getter)
{
    if (!getter(c1).Equals(getter(c2))
    {
        getter(c1) = getter(c2);
    }
}

Example intended usage:

Thing thing1 = new Thing(field1: 0, field2: "foo");
Thing thing2 = new Thing(field1: -5, field2: "foo");
UpdateIfChanged(thing1, thing2, (Thing t) => ref t.field1);
UpdateIfChanged(thing1, thing2, (Thing t) => ref t.field2);

Is there any way to specify a Func type or any kind of generic type restriction that would make this valid by requiring that getter return a reference? I tried Func<TClass, ref TField>, but it doesn't appear to be valid syntax.

Jon Skeet
people
quotationmark

You need to declare your own delegate type for it. For example:

using System;

public class Thing
{
    public int field1;
    public string field2;    
}

public delegate ref TOutput FuncRef<TInput, TOutput>(TInput input);

public class Test
{
    public static void Main()
    {
        Thing thing1 = new Thing { field1 = 0, field2 = "foo" };
        Thing thing2 = new Thing { field1 = -5, field2= "foo" };
        UpdateIfChanged(thing1, thing2, (Thing t) => ref t.field1);
        UpdateIfChanged(thing1, thing2, (Thing t) => ref t.field2);
    }

    static void UpdateIfChanged<TInput, TOutput>(TInput c1, TInput c2, FuncRef<TInput, TOutput> getter)
    {
        if (!getter(c1).Equals(getter(c2)))
        {
            getter(c1) = getter(c2);
        }
    }
}

(Note the use of "field" instead of "property" everywhere.)

people

See more on this question at Stackoverflow