Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 898
novog Avatar asked Aug 18 '17 15:08

novog


People also ask

How do I return a generic null?

So, to return a null or default value from a generic method we can make use default(). default(T) will return the default object of the type which is provided.

What is generic function and class?

In some systems for object-oriented programming such as the Common Lisp Object System (CLOS) and Dylan, a generic function is an entity made up of all methods having the same name. Typically a generic function is an instance of a class that inherits both from function and standard-object.

What is generic function example?

The print() function is an example of a generic function. A generic function is simply a function that performs a common task by dispatching its input to a particular method-function that is selected on the basis of the class of the input to the generic function.

Which are functions that operate on generic types?

Generic functions are functions declared with one or more generic type parameters. They may be methods in a class or struct , or standalone functions. A single generic declaration implicitly declares a family of functions that differ only in the substitution of a different actual type for the generic type parameter.


1 Answers

You won't be able to use Func, because it doesn't return the result by reference. You'll need to create a new delegate that uses a ref return:

public delegate ref TResult RefReturningFunc<TParameter, TResult>(TParameter param);

Then changing your function to use that delegate is enough for it to work:

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

Note that a property cannot be returned by reference. You could return a field by reference, or any other variable, but a property is not a variable.

like image 139
Servy Avatar answered Oct 25 '22 03:10

Servy