Я просто столкнулся с самой странной штукой, и сейчас я немного mind = blown...
Следующая программа компилируется отлично, но при ее запуске вы получаете RuntimeBinderException
при попытке прочитать Value
. '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?
}
}
Здесь часть разума. Переместите вложенный тип Factory+Empty
вне класса Factory
, например:
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
class Factory...
И программа работает отлично, кто-нибудь может объяснить, почему это?
ИЗМЕНИТЬ
В моем приключении кодирования я, конечно, сделал то, о чем я должен был подумать в первую очередь. Вот почему вы видите, что я немного рассмешался о различии между частным и внутренним. Это было связано с тем, что я установил InternalsVisibleToAttribute
, который сделал мой тестовый проект (который потреблял биты в этом экземпляре) вел себя так, как они делали, что было по дизайну, хотя и намекало на меня с самого начала.
Прочитайте ответ Эрика Липперта за хорошее объяснение остальных.
Что меня насторожило, так это то, что динамическое связующее воспринимает видимость типа рассматриваемого экземпляра. У меня много опыта работы с JavaScript, и как программист на JavaScript, где на самом деле нет такой вещи, как публичный или частный, меня полностью обманули тем фактом, что важна видимость, я имею в виду, что я обращался к этому члену так, как будто он был типа публичного интерфейса (я думал, что динамический просто синтаксический сахар для отражения), но динамическое связующее не может сделать такое предположение, если вы не дадите ему намек, используя простой листинг.