TL;DR
在接口(interface)中隐藏属性以便我可以更改其声明以返回原始属性的派生类型有什么问题?
我确信以前肯定有人问过这个问题,但我找不到它,对于这么长的问题深表歉意。
假设我有这种情况:
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;}
}
我的类(class)是
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
添加了任何内容?
或者我最初的计划只是将方法隐藏在派生类型中以返回原始方法的派生类型可以吗?
最佳答案
Or is my original plan of just hiding the method in the derived type to return a derived type of the original method ok?
只要它的意思完全相同,我认为就可以了。您可以在标准库中看到类似的内容,带有 IDbConnection.CreateCommand
(返回 IDbCommand
)和 SqlConnection.CreateCommand
(返回 SqlCommand
)例如。
在这种情况下,它使用 IDbConnection
的显式接口(interface)实现版本不同,但原理是一样的。
您还可以在 IEnumerator<T>.Current
中看到它与 IEnumerator.Current
和IEnumerable<T>.GetEnumerator()
与 IEnumerable.GetEnumerator()
.
我只会在弱类型方法的实现仅返回调用强类型方法的结果的情况下使用它,但使用隐式转换。当他们真正开始做不同的事情时,以后就变得更难以推理。
关于c# - 在返回派生类型的派生接口(interface)中隐藏属性是否可以接受?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9783083/