TL; DR
Что не так с сокрытием свойства в интерфейсе, чтобы я мог изменить его объявление, чтобы оно возвращало производный тип исходного свойства?
Я уверен, что это должно было быть задано раньше, но я не могу найти его, и извиняюсь за длинный вопрос.
Скажите, у меня такая ситуация:
public interface A
{
B TheB{get;}
}
public interface MoreSpecificA : A
{
MoreSpecificB TheMoreSpecificB{get;}
}
public interface B{...}
public interface MoreSpecificB:B{...}
Я быкак пользователи MoreSpecificA
, чтобы иметь возможность добраться до B, который является MoreSpecificB
.Они могут сделать это, вызвав TheB
и разыграв его, или они могут вызвать метод TheMoreSpecificB
.Я также мог бы объявить MoreSpecificA
примерно так:
public interface MoreSpecificA : A
{
new MoreSpecificB TheB{get;}
}
, чтобы теперь они могли просто использовать тот же метод и получить MoreSpecificB
.
Использование new
для сокрытия метода заставляет мои зубы нервничать, так почему это плохая идея?Это кажется разумным, чтобы сделать здесь.
Общее предложение в большинстве случаев, которое я видел для этого, заключается в том, чтобы вместо этого использовать дженерики, но, похоже, проблема в том, что если у меня есть MoreSpecificA
, и я хочу вернуть его в методекоторый объявляет тип возвращаемого значения как A
, тогда я должен иметь MoreSpecificA
extend A
, что дает неоднозначность при доступе к TheB
в экземпляре MoreSpecificA
, поскольку он не знает, хотите ли вы A.TheB
или MoreSpecificA.TheB
public interface ABase<T> where T : B
{
T TheB{get;}
}
public interface A : ABase<B>
{
}
public interface MoreSpecificA : ABase<MoreSpecificB>,A
{
}
public class blah
{
public A GetA(MoreSpecificA specificA)
{
return specificA; //can't do this unless MoreSpecificA extends A
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here, if MoreSpcificA extends A
}
}
, которая может быть решена путем объявления нового TheB на MoreSpecificA (но снова новой проблемы).
Если MoreSpecificA не расширяет A, то первый метод в классе blah
выше жалуется, так как теперь MoreSpcificA не может быть преобразовано в A.
Во время написания этого я заметил, что если я объявлю свою BaseA противоположной, как это:
public interface ABase<out T> where T : B
{
T TheB{get;}
}
имой класс будет
public class blah
{
public ABase<B> GetA(MoreSpecificA specificA)
{
return specificA;
}
public B GetB(MoreSpecificA specificA)
{
return specificA.TheB; //compiler complains about ambiguity here
}
}
Тогда я получу лучшее из обоих миров.Применимость этого решения зависит от того, добавляет ли A
что-либо к ABase
?
Или мой первоначальный план состоит в том, чтобы просто скрыть метод в производном типе, чтобы вернуть производный тип исходного метода, хорошо?