让我们以接口IQueryable<T>
为例:
public interface IQueryable<T> : IQueryable, IEnumerable;
由于IQueryable本身实现了IEnumerable:
public interface IQueryable : IEnumerable;
为什么在第一个声明中,IQueryable必须显式实现IEnumerable呢?这与类继承不同,后者不需要显式地继承“祖父类”?
让我们以接口IQueryable<T>
为例:
public interface IQueryable<T> : IQueryable, IEnumerable;
由于IQueryable本身实现了IEnumerable:
public interface IQueryable : IEnumerable;
public class Button : ButtonBase,IButtonControl
and not the following ...
public class Button : ButtonBase,Control,Component,MarshalByRefObject,Object
这不是真的。我怀疑你在Visual Studio中右键点击这些类/接口,然后点击“转到定义”,这就是元数据告诉你的。如果你想真正理解发生了什么,这里有一个例子:
public interface IAddTwo
{
int AddTwo(int x);
}
public interface IAddTwoOrThree : IAddTwo
{
int AddThree(int y);
}
public class AddTwoOrThree : IAddTwoOrThree
{
public int AddTwo(int q)
{
return q + 2;
}
public int AddThree(int z)
{
return z + 3;
}
}
AddTwoOrThree : IAddTwoOrThree, IAddTwo
哇!这就是为什么你在MSDN上看到的东西是这样的。他们展示的是元数据,而不是他们的程序员编写的代码。
这是因为接口继承是一种纯语言糖,当编译成IL时,该接口会显式实现链中的所有接口,因此查看IQueryable<T>
的签名最终会变成:
.class public interface abstract auto ansi IQueryable<+ T>
implements [mscorlib]System.Collections.Generic.IEnumerable`1<!T>, System.Linq.IQueryable, [mscorlib]System.Collections.IEnumerable
{
}
正确的定义是:
public interface IQueryable<out T> : IEnumerable<T>, IQueryable { }
public interface IQueryable : IEnumerable {
Expression Expression { get; }
Type ElementType { get; }
// the provider that created this query
IQueryProvider Provider { get; }
}
#if SILVERLIGHT
public interface IQueryable<T> : IEnumerable<T>, IQueryable {
#else
public interface IQueryable<out T> : IEnumerable<T>, IQueryable {
#endif
}
public interface IQueryProvider{
IQueryable CreateQuery(Expression expression);
IQueryable<TElement> CreateQuery<TElement>(Expression expression);
object Execute(Expression expression);
TResult Execute<TResult>(Expression expression);
}
public interface IOrderedQueryable : IQueryable {
}
#if SILVERLIGHT
public interface IOrderedQueryable<T> : IQueryable<T>, IOrderedQueryable {
#else
public interface IOrderedQueryable<out T> : IQueryable<T>, IOrderedQueryable {
#endif
}