Почему C# не позволяет типам, использующим композицию, иметь неявные преобразования для интерфейсов? [дубликат]
Возможные Дубликаты:
почему я не могу использовать интерфейс с явной оператора?
когда я делаю это:
public struct Effect
{
public IEffect IEffect { get; private set; }
public Effect ( IEffect effect )
{
this.IEffect = effect;
}
public static implicit operator IEffect ( Effect effect )
{
return effect.IEffect;
}
public static explicit operator Effect ( IEffect effect )
{
return new Effect ( effect );
}
}
Я получаю такую ошибку компилятора:
'.Эффект.неявный оператор Объекта imageeditor.Ieffect, Который(Объекта Imageeditor.Эффект'): пользовательские преобразования в или из интерфейс не разрешен.
почему они не пускают? Это не хорошо практика?
3 ответов
Это подробно описано в разделе 10.10.3 спецификации языка C#.
резюме причина почему хотя ...
- операторы преобразования не должны заменять встроенные преобразования. Позволяя это просто приводит к чрезвычайно запутанному поведению
- В общем случае невозможно определить, заменяет ли неявное преобразование в интерфейс встроенное преобразование и, следовательно, оно запрещено
основная причина заключается в том, что объект, реализующий интерфейс, всегда неявно конвертируется в свой базовый класс и всегда явно конвертируется из своего базового класса в себя. Переопределение этого поведения является избыточным и запутанным, и вы не можете переопределить все необходимое поведение, чтобы заставить его работать должным образом, и поэтому он запрещен. В вашем случае вы переопределяете некоторое, но не все поведение наследования. Например, рекомендуется при явном приведении:
IEffect anIEffectInstance = GetEffectAsInterface();
if(anIEffectInstance is Effect) //<--you cannot override this behavior to return true,
var interfaceAscConcrete = (Effect)anIEffectInstance; //<-- so this overridden code would never execute
звучит как вопрос для Джона Скита или что-то в этом роде, но я все равно попытаюсь.
неявный оператор, который вы описали, в основном будет просто ненужным. Если Effect
уже реализует IEffect
, вы можете использовать Effect
везде, где вам нужен объект, реализующий IEffect
не беспокоясь о пользовательском преобразовании.
проблема явного оператора может быть немного более философской. Мое понимание заключается в том, что смысл имплицитного и явные преобразования-это преобразование объекта одного типа в объект другого типа, связь с которым по какой-то причине еще не очевидна компилятору. Однако интерфейс не является объектом. Невозможно создать экземпляр интерфейса напрямую; скорее, интерфейс должен быть реализован каким-то классом. При использовании неявных или явных преобразований результирующий объект не связан по типу с предыдущим объектом. Это означает, что объект, полученный в результате преобразования необходимо иметь возможность стоять независимо и иметь фактический тип объекта, которого сам по себе интерфейс не имеет.
возможно, более прямо: каким будет конкретный тип результата неявного преобразования? Компилятор не может знать, поэтому он не может создать экземпляр объекта.
если вы действительно должны сделать что-то подобное, вы хотели бы создать абстрактный базовый класс, который реализует интерфейс. Затем вы сможете "конвертировать" в и из абстрактный базовый класс, который имеет тип object.