Можно ли отследить присваивание результата выполнения метода?
Условно есть MyLib1.dll в которой есть следующий метод:
public static int Sum(int a, int b)
{
return a + b;
}
Так же есть какой-то юзер моей библиотеки который вызывает этот метод. Могу ли я отследить присваивание значения которое вернет мой метод?
Т.е условно это выглядит так (в юзерском коде):
int result = MyLib.LibClass.Sum(5, 5);
После выполнения этого метода выделяется (возможно нет, но не суть) память под result, и в своей MyLib1.dll я хочу узнать было ли присваивание значения. Как это можно реализовать и можно ли вообще?
Ответы (2 шт):
Ладно, напишу.
Допустим, что в этой теме мы обсуждаем всякое странное!
Используем Ref returns and ref locals.
В метод добавим ключевое слово ref в сигнатуру и в место возврата:
namespace MyLib
{
public static class LibClass
{
static int c;
public static ref int Sum(int a, int b)
{
c = a + b;
return ref c;
}
}
}
Теперь, если при вызове тоже использовать ref, переменная будет ссылаться на память, выделенную для поля c.
ref int x = ref MyLib.LibClass.Sum(5, 5);
Console.WriteLine(x);
ref int y = ref MyLib.LibClass.Sum(5, 6);
Console.WriteLine(x);
Console.WriteLine(y);
Это выведет:
10
11
11
Видно, что значение x поменялось при втором вызове.
А если не использовать ref:
int a = MyLib.LibClass.Sum(5, 5);
Console.WriteLine(a);
int b = MyLib.LibClass.Sum(5, 6);
Console.WriteLine(a);
Console.WriteLine(b);
будет вывод:
10
10
11
В этом варианте значение a остаётся прежним.
Не знаю, зачём всё это. Ну а вдруг!
Можно использовать операторы преобразования. User-defined conversion operators.
namespace MyLib
{
public readonly struct MyNumber
{
private readonly int _number;
public MyNumber(int number) => _number = number;
public static implicit operator int(MyNumber number)
{
Console.WriteLine("присваивание");
return number._number;
}
public static implicit operator MyNumber(int number)
{
Console.WriteLine("вызов");
return new MyNumber(number);
}
public override string ToString() => _number.ToString();
}
public static class LibClass
{
public static MyNumber Sum(int a, int b)
{
return a + b;
}
}
}
Перегружены операторы присваивания. В них мы можем вставить код, реагирующий на их вызов.
Я оба оператора сделал неявными (implicit), что не рекомендуется. Но для наших целей сойдёт.
Пробуем:
int x = MyLib.LibClass.Sum(5, 5);
Выдаст
вызов
присваивание
То есть можно узнать, было ли присваивание!
Если написать
MyLib.LibClass.Sum(5, 5);
Результат будет
вызов
Присваивания нет!
Однако, если написать
var y = MyLib.LibClass.Sum(5, 5);
или, что равноценно
MyNumber z = MyLib.LibClass.Sum(5, 5);
Результат
вызов
То есть о присваивании в этом случае мы не узнаем.