首页 > 解决方案 > C# 接口无法实例化,为什么我可以在不指定具体类型的情况下使用 IEnumerable

问题描述

我知道接口无法实例化,但可以创建实现接口的对象的实例。

但是在这个例子中,我使用的是一个接口变量,它从来没有被实例化为一个类的对象。

public static IEnumerable<Person> GetPeople()
{
    IEnumerable<Person> people = AMethod<IEnumerable<Person>>();
    return people;
}

var people = MyClass.GetPeople();
// ... operations on the people variable

因此,我绝不是指实现 IEnumerable 的数组或列表或其他类型。当我调试此代码时,调试器显示人员变量的类型为 IEnumerable<Person>。但是,如果接口不是“真实的东西”而只是一个合同,那又如何呢?就像在内存中一样,这是一个数组、一个列表还是其他什么?我正在学习关于接口的课程,但我无法理解这一点。

标签: c#.net

解决方案


像这样的抽象有用的东西IEnumerable<T>是由许多类实现的。

例如:

aList<T> 一个IEnumerable<T>

一个ImmutableArray<T> 一个IEnumerable<T>

数组T[] 一个IEnumerable<T>(尽管它有点编译器的魔力,请参阅注释)。

说一个方法返回一个IEnumerable<T>只是意味着这个方法将返回一个实现的东西IEnumerable,你不需要关心哪个,但是你可以依赖接口已经实现的事实,因此可以foreach在上面使用和 linq 方法

如果您只需要能够使用枚举某些东西foreach或应用 linq 方法,则可以隐藏实际的实现(数组或列表或其他)并IEnumerable改用它。

一般来说,为什么要使用抽象?这是一个简短的开始答案。

想象一下,您依赖于特定的实现,例如List<T>,然后您将其作为List<T>参数等传递给其他函数......您的代码会像这样增长。

有一天,您意识到List<T>出于某种原因(出于性能考虑,或者因为您现在使用另一个返回某种其他类的库),这不是一个好的选择。

现在你需要解开所有依赖这个List假设的东西。


推荐阅读