c# - 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>。但是,如果接口不是“真实的东西”而只是一个合同,那又如何呢?就像在内存中一样,这是一个数组、一个列表还是其他什么?我正在学习关于接口的课程,但我无法理解这一点。
解决方案
像这样的抽象有用的东西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
假设的东西。
推荐阅读
- c - 并非所有 malloc 的内存都是“堆”并且每个块在虚拟内存中不连续?
- api - setState() 在构造函数中调用:_WeatherState#823a5(生命周期状态:已创建,没有小部件,未安装)错误颤动
- google-admin-sdk - GSuite Vault API:任何方式以编程方式获取用户列表?
- excel - 使用一列中的数据进行 Excel VBA 多表搜索
- oracle - 为什么更新时触发器不触发
- arrays - VBA将过滤后的表数据获取到数组
- python - 向 Python enum.IntEnum 添加属性和起始值
- swift - 在 swift 上编写算法时出错
- c# - 如何在 C# 中以另一种方法访问对象?
- c# - 在 DataAdapter 中,当我们必须手动更改列中的值时,为什么我们使用更新 SQL 语句