C # tipo dinâmico pegadinha
Eu acabei de me deparar com a coisa mais estranha e eu sou um poucomente = soprado no momento...
O programa a seguir compila bem, mas quando você executá-lo você recebe umRuntimeBinderException
quando você tenta lerValue
. 'object' does not contain a definition for 'Value'
class Program
{
interface IContainer
{
int Value { get; }
}
class Factory
{
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
static IContainer nullObj = new Empty();
public IContainer GetContainer()
{
return nullObj;
}
}
static void Main(string[] args)
{
dynamic factory = new Factory();
dynamic container = factory.GetContainer();
var num0 = container.Value; // WTF!? RuntimeBinderException, really?
}
}
Aqui está a parte do sopro da mente. Mover o tipo aninhadoFactory+Empty
fora doFactory
classe, assim:
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
class Factory...
E o programa funciona muito bem, alguém se importa em explicar por que isso acontece?
EDITARNa minha aventura de codificação, eu fiz algo que deveria ter pensado primeiro. É por isso que você me vê divagando um pouco sobre a diferença entre classe privada e interna. Isso foi porque eu tinha definido oInternalsVisibleToAttribute
o que fez com que meu projeto de teste (que estava consumindo os bits nesta instância) se comportasse da maneira que eles faziam, o que era tudo por design, embora aludindo a mim desde o começo.
Leia a resposta de Eric Lippert para uma boa explicação do resto.
O que me chamou a atenção foi que o fichário dinâmico leva em conta a visibilidade do tipo de instância. Eu tenho muita experiência em JavaScript e como um programador de JavaScript onde realmente não existe algo como público ou privado, eu estava completamente enganado pelo fato de que a visibilidade importava, quero dizer, afinal, eu estava acessando esse membro como se era do tipo de interface pública (eu achava que dinâmica era simplesmente açúcar sintático para reflexão), mas o aglutinante dinâmico não pode fazer tal suposição a menos que você dê uma dica, usando um simples elenco.