TL;博士
在接口中隐藏属性以便我可以更改其声明以返回原始属性的派生类型有什么问题?
我敢肯定这一定是以前问过的,但我找不到它,并为这个冗长的问题道歉。
说我有这种情况:
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
扩展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
}
}
这可以通过在 MoreSpecificA 上声明一个新的 TheB 来解决(但又是新问题)。
如果 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
?
还是我最初的计划只是将方法隐藏在派生类型中以返回原始方法的派生类型好吗?