我知道我们不能创建Interface的实例。但是为什么我们可以在左边写Interface呢?这些只是接口的引用(对于实现此接口的类),而不是实例吗?
如果我们不能创建接口实例,那么在这个示例中P是什么类型?
string[] names = {"John", "Bob", "Mark"};
IEnumerable<string> P = names.Where(n => n.Contains('o'));发布于 2014-02-26 14:02:40
P是IEnumerable<string>型的
这里声明局部变量P的类型。
P保存IEnumerable<string>类型,虽然不直接实例化接口,但可以实例化一个具体的类,但只需保存对接口的引用。
Where()调用在这里返回的实例只需要遵守IEnumerable<string>定义的契约。
发布于 2014-02-26 14:05:00
不能创建接口实例,但可以创建实现接口的实例。
在您的示例中,您只需获取已知遵守p定义的契约的内容( IEnumerable<string> )。
如果你用稍微简单一些的术语来看待这个概念,就会更容易理解它:
IBeast mrJuggles = new Tiger();Mr.Juggles现在是老虎,但也是IBeast。我们没有显式地创建一个IBeast,我们只是指定我们所创建的东西将作为一个IBeast来运行,因此我们将能够将它作为一个IBeast来处理。
发布于 2014-02-26 14:06:18
我会尽量从概念上来解释这一点。
但是为什么我们可以在左边写界面呢?
我们可以这样做,因为它的意思是:“这个对象是实现这个接口的。”
接口本身并不是“东西”--这就是为什么不能直接实例化它的原因--它只是一个契约。
接口是无用的,除非您定义了一些对象,以保证实现它所表示的契约(并公开此类方法等等)。这就是你对接口的使用。没有这个,他们就没有意义了。
合同本身是一个抽象的概念。它需要一些东西来体现它--一个充满它的物体。
请看以下示例:
using System.Collections.Generic;
namespace App
{
class Program
{
class Example
{
List<string> list = new List<string> { "a", "b", "c" };
public IEnumerable<string> AsEnumerable()
{
return list;
}
}
static void Main(string[] args)
{
IEnumerable<string> foo = new Example().AsEnumerable();
List<string> bar = (List<string>)foo;
}
}
}你知道它不会坠毁吗?
这一行中的IEnumerable<string>:
IEnumerable<string> foo = new Example().AsEnumerable();实际上意思是:"foo是我们知道的实现IEnumerable的东西“。
但还是有些东西。它不可能仅仅是IEnumerable和什么都没有,只是。IEnumerable只是我们碰巧知道的东西。
否则我们就不能把它放回List<string>,对吗?(这实际上是C#中的一个常见警告,因为调用方可以执行此转换,因此可以访问Add和Remove方法,并处理列表中的内容,尽管我们不打算这样做。是封装泄漏)。
换句话说:IEnumerable<string>就是,我们看待这个对象的方式是。
编辑:
正如@Kjartan所建议的,您可以这样验证所有这些:
bool isFooIEnumerable = foo is IEnumerable<string>; // it's true
bool isBarIEnumerable = bar is IEnumerable<string>; // true again
bool isFooList = foo is List<string>; // yup. true
bool isBarList = bar is List<string>; // true all the wayhttps://stackoverflow.com/questions/22043643
复制相似问题