- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我读了一本书“CLR via C# Fourth Edition”。我无法理解一种说法:
So, for example, if you have the following line of code:
FileStream[] fsArray;
then when the CLR creates the
FileStream[]
type, it will cause this type to automatically implement theIEnumerable<FileStream>
,ICollection<FileStream>
, andIList<FileStream>
interfaces. Furthermore, theFileStream[]
type will also implement the interfaces for the base types:IEnumerable<Stream>
,IEnumerable<Object>
,ICollection<Stream>
,ICollection<Object>
,IList<Stream>
, andIList<Object>
.
我用这段代码测试了这条语句:
FileStream[] fsArray = new FileStream[0];
string s = null;
foreach (var m in fsArray.GetType().GetInterfaces())
s += m.ToString() + Environment.NewLine;
结果,我得到了这个:
System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.IO.FileStream]
System.Collections.Generic.ICollection`1[System.IO.FileStream]
System.Collections.Generic.IEnumerable`1[System.IO.FileStream]
System.Collections.Generic.IReadOnlyList`1[System.IO.FileStream]
System.Collections.Generic.IReadOnlyCollection`1[System.IO.FileStream]
没有执行 IEnumerable<Stream>
和别的!我在某处弄错了吗?还是 Jeffrey Richter 弄错了?
此外,我认为它是无意义的。因为数组支持协方差。
最佳答案
There is no implementation of IEnumerable and others!
没有。然而,IList<Stream> streamList = fsArray;
将工作。你可以使用 streamList
正如您所期望的那样,尽管如果您尝试对数组执行无效的操作会出现运行时异常(只要该数组是从零开始的并且具有单一维度——Microsoft 的说法是“SZ 数组”——否则它是不允许的) .
想看更糟的东西吗?
var listMap = typeof(List<FileStream>).GetInterfaceMap(typeof(IList<FileStream>)); // This works fine.
var arrMap = typeof(typeof(FileStream[]).GetInterfaceMap(typeof(IList<FileStream>)); // This throws `ArgumentException`
所以在这方面,FileStream[]
甚至没有实现 IList<FileStream>
;如果确实如此,那么上面的行肯定应该有效。
从 .NET 4.0 开始,我们得到了一条有趣的线索。在此之前,ArgumentException
会有 "Interface not found"
的消息,就像我们试图在 int
上获取该接口(interface)一样或 string[]
.现在是"Interface maps for generic interfaces on arrays cannot be retrived."
[原文如此]
如果我们尝试获取 IList<Stream>
的接口(interface)映射,它也会给我们这个但不适用于完全不受支持的接口(interface),如 IList<bool>
.
这里发生了一些不寻常的事情。
它是什么 FileStream[]
根本不直接支持任何通用接口(interface),与 class
相同或 struct
会的。
取而代之的是一个名为 SZArrayHelper
的 stub 类它在运行时为从零开始的一维数组提供这些接口(interface)。关于 .NET Core Version 的评论信息丰富:
//----------------------------------------------------------------------------------------
// ! READ THIS BEFORE YOU WORK ON THIS CLASS.
//
// The methods on this class must be written VERY carefully to avoid introducing security holes.
// That's because they are invoked with special "this"! The "this" object
// for all of these methods are not SZArrayHelper objects. Rather, they are of type U[]
// where U[] is castable to T[]. No actual SZArrayHelper object is ever instantiated. Thus, you will
// see a lot of expressions that cast "this" "T[]".
//
// This class is needed to allow an SZ array of type T[] to expose IList<T>,
// IList<T.BaseType>, etc., etc. all the way up to IList<Object>. When the following call is
// made:
//
// ((IList<T>) (new U[n])).SomeIListMethod()
//
// the interface stub dispatcher treats this as a special case, loads up SZArrayHelper,
// finds the corresponding generic method (matched simply by method name), instantiates
// it for type <T> and executes it.
//
// The "T" will reflect the interface used to invoke the method. The actual runtime "this" will be
// array that is castable to "T[]" (i.e. for primitivs and valuetypes, it will be exactly
// "T[]" - for orefs, it may be a "U[]" where U derives from T.)
//----------------------------------------------------------------------------------------
这就是发生的事情。如果你尝试投 fsArray
至 IList<Stream>
然后你让这个类(class)为你打电话。如果您调用 GetInterfaces()
您会得到类似的 stub 代码,仅提供与数组类型相关的代码。在任何一种情况下fsArray
确实实现了您引用的书中提到的所有接口(interface),但它的实现方式与class
不同。或 struct
可以。
(类推一下 int
如何既可以是 32 位值的四个字节又可以是具有接口(interface)实现、方法覆盖等的“完整”对象)
所以这本书是正确的,但您也没有遗漏任何东西,因为当类型实现接口(interface)时我们期望发生的某些事情并没有发生。
Furthermore, I think it is mean-less. Because Arrays support co-variance.
支持协方差并不意味着他们会实现给定的接口(interface),反之亦然。特别是因为数组的(可以说是损坏的)协变与接口(interface)中的协变非常不同,并且早于它,而且实际上让数组实现通用接口(interface)也早于接口(interface)协变。
但是,决定FileStream[]
确实应该实现 Stream[]
确实与数组协变有关(否则这个决定会非常错误),但它需要额外的帮助 SZArrayHelper
提供,而不是被它自动包含。
关于c# - 数组中自动实现的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31832806/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!