Common functions and ref ref in C # 7.0

Is it possible to use the link return function in C # 7.0, to define a general function that can perform both comparison and field updating in two instances of an object? I imagine 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); } } 

An example of the intended use:

 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 it possible to specify a type of Func or any type restriction of a generic type that will make this valid by requiring getter to return the link? I tried Func<TClass, ref TField> , but it is not a valid syntax.

+5
source share
2 answers

You cannot use Func because it does not return the result by reference. You will need to create a new delegate that uses ref ref:

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

Then you need to change your function to use this delegate:

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

Please note that the property cannot be returned by reference. You can return a field by reference or any other variable, but the property is not a variable.

+6
source

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

 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 "fields" instead of "properties" everywhere.)

+4
source

Source: https://habr.com/ru/post/1271004/


All Articles