Iai*_*ain 141
如果实现两个具有相同方法和不同实现的接口,则必须明确实现.
public interface IDoItFast
{
void Go();
}
public interface IDoItSlow
{
void Go();
}
public class JustDoIt : IDoItFast, IDoItSlow
{
void IDoItFast.Go()
{
}
void IDoItSlow.Go()
{
}
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*l B 63
隐藏非首选成员很有用.例如,如果你同时实现这两者IComparable<T>
,IComparable
那么隐藏IComparable
重载通常会更好,不会让人觉得你可以比较不同类型的对象.同样,某些接口不符合CLS IConvertible
,因此,如果您没有明确实现该接口,那么需要符合CLS的语言的最终用户将无法使用您的对象.(如果BCL实施者没有隐藏基元的IConvertible成员,那将是非常灾难性的:))
另一个有趣的注意事项是,通常使用这样的构造意味着显式实现接口的struct只能通过装箱到接口类型来调用它们.你可以通过使用泛型约束来解决这个问题::
void SomeMethod<T>(T obj) where T:IConvertible
Run Code Online (Sandbox Code Playgroud)
当你将一个int传递给它时,不会对它进行封装.
Wie*_*sma 36
明确实现接口的其他一些原因:
向后兼容性:如果ICloneable
接口更改,实现方法类成员不必更改其方法签名.
更清洁的代码:如果Clone
从ICloneable中删除该方法,将会出现编译器错误,但是如果您隐式实现该方法,则最终可能会使用未使用的"孤立"公共方法
强类型:为了用一个例子来说明supercat的故事,这将是我首选的示例代码,当您直接将其作为实例成员调用时,ICloneable
显式实现允许Clone()
强类型MyObject
:
public class MyObject : ICloneable
{
public MyObject Clone()
{
// my cloning logic;
}
object ICloneable.Clone()
{
return this.Clone();
}
}
Run Code Online (Sandbox Code Playgroud)
sup*_*cat 12
另一个有用的技术是让函数的方法的公共实现返回一个比接口中指定的更具体的值.
例如,一个对象可以实现ICloneable
,但仍然有其公开可见的Clone
方法返回其自己的类型.
同样,一个IAutomobileFactory
可能有一个Manufacture
方法返回一个Automobile
,但是一个FordExplorerFactory
实现IAutomobileFactory
的Manufacture
方法可能让它的方法返回一个FordExplorer
(派生自的Automobile
).知道它有一个FordExplorerFactory
可以FordExplorer
在一个对象返回的对象上使用特定属性FordExplorerFactory
而不必进行类型转换的代码,而只知道它有某种类型的代码只会IAutomobileFactory
将其返回作为一个Automobile
.
当你有两个具有相同成员名称和签名的接口时,它也很有用,但是想根据它的使用方式改变它的行为.(我不建议像这样编写代码):
interface Cat
{
string Name {get;}
}
interface Dog
{
string Name{get;}
}
public class Animal : Cat, Dog
{
string Cat.Name
{
get
{
return "Cat";
}
}
string Dog.Name
{
get
{
return "Dog";
}
}
}
static void Main(string[] args)
{
Animal animal = new Animal();
Cat cat = animal; //Note the use of the same instance of Animal. All we are doing is picking which interface implementation we want to use.
Dog dog = animal;
Console.WriteLine(cat.Name); //Prints Cat
Console.WriteLine(dog.Name); //Prints Dog
}
Run Code Online (Sandbox Code Playgroud)
它可以使公共接口更清晰,以显式实现接口,即您的File
类可以IDisposable
显式实现并提供一个公共方法Close()
,这可能对消费者更有意义Dispose(
.
F#仅提供显式接口实现,因此您必须始终转换为特定接口以访问其功能,这使得接口的使用非常明确(无双关语).
显式实现的另一个原因是可维护性。
当一个类变得“忙碌”时——是的,它发生了,我们并不都有重构其他团队成员的代码的奢侈——然后有一个明确的实现可以清楚地表明一个方法在那里满足接口契约。
所以它提高了代码的“可读性”。