具体类如何隐藏它实现的接口的成员
本文关键字:实现 隐藏 接口 成员 何隐藏 | 更新日期: 2023-09-27 17:52:16
我将给出一个来自。net的例子。
ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
这里你可以看到ConcurrentDictionary实现字典接口。然而,我不能从ConcurrentDictionary实例访问Add<TKey,TValue>
方法。这怎么可能呢?
IDictionary<int, int> dictionary = new ConcurrentDictionary<int, int>();
dictionary.Add(3, 3); //no errors
ConcurrentDictionary<int, int> concurrentDictionary = new ConcurrentDictionary<int, int>();
concurrentDictionary.Add(3, 3); //Cannot access private method here
更新:
我知道如何访问它,但我不知道显式实现接口可以允许将访问修饰符更改为internal。但它仍然不允许将其设为私有。这是正确的吗?对那部分进行更详细的解释会很有帮助。我还想知道一些有效的用例。
因为IDictionary.Add
方法是由ConcurrentDictionary显式实现的。
要从类中访问它,而不必将变量声明为字典,将其强制转换为所需的接口:
((IDictionary)concurrentDictionary).Add(3, 3)
这是通过显式接口实现的
public interface ISomeInterface
{
void SomeMethod();
}
public class SomeClass : ISomeInterface
{
void SomeInterface.SomeMethod()
{
// ...
}
}
现在,当您有对SomeClass
对象的引用时,您将看不到SomeMethod
方法可用。为了调用它,你必须将对象强制转换回ISomeInterface
…
((ISomeInterface)mySomeClass).SomeMethod();
它是作为显式接口实现的,这意味着您需要一个IDictionary<TKey, TValue>
类型的变量来访问它。
参见ConcurrentDictionary<TKey, TValue>
的文档,在显式接口实现部分。
如果你将并发字典强制转换为IDictionary<TKey, TValue>
,你将能够调用Add
。
我不知道显式实现接口可以允许将访问修饰符更改为internal。但它仍然不允许将其设为私有。这是正确的吗?
不,这是不对的。
显式接口实现不改变访问修饰符。它们改变了你访问以这种方式实现的成员的方式(即要求你使用接口类型的变量)。它们仍然是公共成员,但只能使用接口类型访问,而不能使用实现类型。
显式接口实现。对于一个更简单的例子:
public interface IFoo {
void Bar();
}
public class Foo : IFoo {
void IFoo.Bar() { ... }
}
这里Bar
不是Foo
的公共API
接口显式实现。在下面的例子中,你不能使用一个类的实例来访问Add
方法。
public interface IA
{
void Add();
}
public class A : IA
{
void IA.Add()
{
throw new NotImplementedException();
}
}
访问修饰符未更改;ConcurrentDictionary<TKey, TValue>
通过显式接口实现定义了IDictionary.Add
方法,没有实现Add
方法。
如果您查看类文档,您将看到没有Add
方法存在(因此concurrentDictionary.Add(3, 3);
将类似于调用concurrentDictionary.MethodThatDoesntExist(3, 3);
)。然而,在显式接口实现部分,您可以看到有ICollection.Add
和IDictionary.Add
方法。
这个特性允许一个类实现共享一个方法名的多个接口,而不要求每个接口的实现都是相同的。
感谢大家的精彩回答,其中一个被删除的答案让我对访问修饰符感到困惑。我从相关的问题中找到了一些很好的解释。
Michael Hopcroft的隐式和显式接口实现
Jon Skeet的一些用例
显式实现IDisposable
Brad Abrams的显式成员实现设计指南
令人讨厌的模糊重载,第一部分&第二部分/Eric Lippert