Сообщение Re[35]: Welcome to C# 9.0 от 18.09.2020 11:17
Изменено 18.09.2020 12:12 artelk
Re[35]: Welcome to C# 9.0
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, artelk, Вы писали:
A>>Так что вполне можно было сделать так, что десериализация в иммутабельный рекорд (и класс с init-only свойствами) работала бы без проблем.
НС>Нельзя. Я тебе еще раз напомню, что нормальные десериализаторы не через рефлексию работают.
А FieldInfo/PropertyInfo они откуда берут? Для кодогеренации они тоже нужны.
Кстати, вот попробовал с SRE:
readonly на поле успешно проигнорировался.
НС>Здравствуйте, artelk, Вы писали:
A>>Так что вполне можно было сделать так, что десериализация в иммутабельный рекорд (и класс с init-only свойствами) работала бы без проблем.
НС>Нельзя. Я тебе еще раз напомню, что нормальные десериализаторы не через рефлексию работают.
А FieldInfo/PropertyInfo они откуда берут? Для кодогеренации они тоже нужны.
Кстати, вот попробовал с SRE:
public delegate void ClassFieldSetter<in T, in TValue>(T target, TValue value) where T : class;
public static class FieldSetterCreator
{
public static ClassFieldSetter<T, TValue> CreateClassFieldSetter<T, TValue>(FieldInfo field)
where T : class
{
return CreateSetter<T, TValue, ClassFieldSetter<T, TValue>>(field);
}
private static TDelegate CreateSetter<T, TValue, TDelegate>(FieldInfo field)
{
return (TDelegate)(object)CreateSetter(field, typeof(T), typeof(TValue), typeof(TDelegate));
}
private static Delegate CreateSetter(FieldInfo field, Type instanceType, Type valueType, Type delegateType)
{
var paramType = instanceType.IsValueType ? instanceType.MakeByRefType() : instanceType;
var setter = new DynamicMethod("", typeof(void),
new[] { paramType, valueType },
field.DeclaringType.Module, true);
var generator = setter.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stfld, field);
generator.Emit(OpCodes.Ret);
return setter.CreateDelegate(delegateType);
}
}
public class Foo
{
private readonly int x;
public int X => x;
}
class Program
{
static void Main()
{
var x = typeof(Foo).GetField("x", BindingFlags.Instance | BindingFlags.NonPublic);
var setX = FieldSetterCreator.CreateClassFieldSetter<Foo, int>(x);
var foo = new Foo();
setX(foo, 42);
Console.WriteLine(foo.X); // 42!
}
}
readonly на поле успешно проигнорировался.
Re[35]: Welcome to C# 9.0
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Здравствуйте, artelk, Вы писали:
A>>Так что вполне можно было сделать так, что десериализация в иммутабельный рекорд (и класс с init-only свойствами) работала бы без проблем.
НС>Нельзя. Я тебе еще раз напомню, что нормальные десериализаторы не через рефлексию работают.
А FieldInfo/PropertyInfo они откуда берут? Для кодогеренации они тоже нужны.
Кстати, вот попробовал с SRE:
readonly на поле успешно проигнорировался.
НС>Здравствуйте, artelk, Вы писали:
A>>Так что вполне можно было сделать так, что десериализация в иммутабельный рекорд (и класс с init-only свойствами) работала бы без проблем.
НС>Нельзя. Я тебе еще раз напомню, что нормальные десериализаторы не через рефлексию работают.
А FieldInfo/PropertyInfo они откуда берут? Для кодогеренации они тоже нужны.
Кстати, вот попробовал с SRE:
public delegate void ClassFieldSetter<in T, in TValue>(T target, TValue value) where T : class;
public static class FieldSetterCreator
{
public static ClassFieldSetter<T, TValue> CreateClassFieldSetter<T, TValue>(FieldInfo field)
where T : class
{
return CreateSetter<T, TValue, ClassFieldSetter<T, TValue>>(field);
}
private static TDelegate CreateSetter<T, TValue, TDelegate>(FieldInfo field)
{
return (TDelegate)(object)CreateSetter(field, typeof(T), typeof(TValue), typeof(TDelegate));
}
private static Delegate CreateSetter(FieldInfo field, Type instanceType, Type valueType, Type delegateType)
{
var setter = new DynamicMethod("", typeof(void), new[] { instanceType, valueType }, field.DeclaringType.Module, true);
var generator = setter.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stfld, field);
generator.Emit(OpCodes.Ret);
return setter.CreateDelegate(delegateType);
}
}
public class Foo
{
private readonly int x;
public int X => x;
}
class Program
{
static void Main()
{
var x = typeof(Foo).GetField("x", BindingFlags.Instance | BindingFlags.NonPublic);
var setX = FieldSetterCreator.CreateClassFieldSetter<Foo, int>(x);
var foo = new Foo();
setX(foo, 42);
Console.WriteLine(foo.X); // 42
}
}
readonly на поле успешно проигнорировался.