Estou me aprofundando na compreensão de reflexão e indicadores e me deparei com um desafio interessante. Digamos que você tenha a seguinte turma:
namespace Foobar
{
internal class Foo()
{
internal static readonly Me = new Foo();
}
}
Posso obter facilmente o valor do campo usando isto:
Assembly a = Assembly.Load("AssemblyWithFoo");
Type t = a.GetType("Foobar.Foo");
FieldInfo fi = t.GetRuntimeFields().First(f => f is { Name: "Me", IsStatic: true });
var bar = fi.GetValue(null);
Mas definir um novo valor nisso não é permitido porque readonly
"Code Access Security" está obsoleto.
fi.SetValue(null, new Foo());
Então eu estava pensando em usar ponteiros unsafe
para alterar esse campo:
var foo = GetFooFromAssembly();
var bar = fi.GetValue(null);
unsafe
{
object* ptr = &bar;
*ptr = foo;
}
Isso funciona porque altera a bar
variável para conter foo
, mas não altera o campo porque a bar
variável é uma "cópia" do campo estático, não o campo em si.
Existe uma maneira de obter o ponteiro para o campo somente leitura estático e definir um novo objeto nele?
Sem reflexão, mas com ponteiros, você pode definir o
static readonly
campo em umfixed
bloco:Com reflexão, a única maneira que encontrei que funciona é com a geração
DynamicMethod
eIL
com base noIL
blocofixed
acima. Comentei opinned
conteúdo porque não deveria ser necessário comstatic
campos — talvez você queira descomentá-los, por precaução:Então: