相关疑难解决方法(0)

数组与List <T>:何时使用哪个?

MyClass[] array;
List<MyClass> list;
Run Code Online (Sandbox Code Playgroud)

当一个优于另一个时,有什么情况?为什么?

.net arrays list

561
推荐指数
7
解决办法
28万
查看次数

列出<T>或IList <T>

任何人都可以向我解释为什么我想在C#中使用IList而不是List?

相关问题:为什么暴露它被认为是不好的List<T>

c# generics list

485
推荐指数
13
解决办法
20万
查看次数

如何在没有在C#中实现属性"Count"的情况下实现IList <T>?

很长一段时间我都对以下内容感到好奇:

int[] array = new int[1];
int iArrayLength = array.Length;    //1
Run Code Online (Sandbox Code Playgroud)

由于数组实现了IList接口,因此允许以下内容:

int iArrayCount = ((IList<int>)array).Count;    //still 1
Run Code Online (Sandbox Code Playgroud)

但:

int iArrayCount = array.Count;  //Compile error. WHY?
int iArrayLength = array.Length;    //This is what we learned at school!
Run Code Online (Sandbox Code Playgroud)

问题:如何IList<T>在不允许在基类上使用数组的情况下实现(特别是int Count { get; }属性IList<T>)?

c# arrays list

25
推荐指数
2
解决办法
1250
查看次数

为什么((IList <T>)数组).ReadOnly = True但是((IList)数组).ReadOnly = False?

我知道在.NET中,所有数组都派生自System.Array并且System.Array类实现IList,ICollectionIEnumerable.实际的数组类型也实现IList<T>,ICollection<T>IEnumerable<T>.

这意味着如果你有一个String[],那么那个String[]对象也是a System.Collections.IList和a System.Collections.Generic.IList<String>;.

不难看出为什么那些IList会被认为是"ReadOnly",但令人惊讶的是......

String[] array = new String[0];
Console.WriteLine(((IList<String>)array).IsReadOnly); // True
Console.WriteLine(((IList)array).IsReadOnly); // False!
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,尝试通过Remove()RemoveAt()方法删除项会导致NotSupportedException.这表明两个表达式都对应于ReadOnly列表,但IList的ReadOnly属性不返回预期值.

怎么会?

.net c# arrays generics

21
推荐指数
2
解决办法
1339
查看次数

System.Array背后的谜团

我们知道System.Array是一个抽象类,无论DataType[]我们使用什么,运行时都会为我们创建一些具体的实现(虽然模糊不清).

请考虑以下代码段.

int[] someInts = { 1, 2, 3, 4 };
IList<int> collection = someInts;
collection.Clear();
Run Code Online (Sandbox Code Playgroud)

collection.Clear()抛出NotSupportedException,没有什么令人惊讶的.当我查看"StackTrace"时,我惊讶地发现它SZArrayHelper在调用堆栈顶部显示了一些奇怪的"类型" .

堆栈跟踪:

   at System.SZArrayHelper.Clear[T]()//Note this.. How???
   at TestApplication.Program.Main()
Run Code Online (Sandbox Code Playgroud)

怎么可能呢?我正在调用Clear()方法,int[]但是调用是如何进行的SZArrayHelper.Clear.请注意,这Clear是一个SZArrayHelper定义如下的实例方法.

private void Clear<T>()
{
    throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
}
Run Code Online (Sandbox Code Playgroud)

谁创建了"SZArrayHelper"的实例,并注意到Clear方法是私有的.我很困惑地看到发生了什么.如果创建了一个"SZArrayHelper"实例并且Clear被调用,那么执行此调用的辅助方法应该出现在"StackTrace"中.但这不是这种情况.

有人可以解释一下幕后发生的事情吗?

注意:

  1. int[]只是和例子,您可以使用任何类型的数组来模拟它.不仅Clear方法Add,Contains等等具有相同的行为..

  2. 我尝试使用反射器插件调试,这给出了相同的结果调试器显示直接调用SZArrayHelper.Clear<T>().

  3. 只是一个谷歌带我到这个.NET阵列,IList,通用算法,以及STL怎么样?.这有助于理解某种魔法落后但神秘仍然存在.

.net c#

12
推荐指数
1
解决办法
1784
查看次数

为什么foreach(array2D中的var i)在多维数组上工作?

给出以下C#代码:

   int[,] array2D = new int[10, 10];
   int sum = 0;

   foreach (var i in array2D)
   {
        sum += i;
   }
Run Code Online (Sandbox Code Playgroud)

问题是:是什么导致类型i被正确推断为int

这并不是一件容易的事,因为array2D是一个矩形阵列.它没有实现IEnumerable<int>.它还实现了一个GetEnumerator()返回a 的方法System.Collections.IEnumerator.因此,我希望这种i类型object.

我的代码使用的是.net 4.03.

相关问题:为什么C#多维数组没有实现IEnumerable?.

.net c# foreach multidimensional-array

10
推荐指数
1
解决办法
256
查看次数

为什么以下代码编译和执行成功?

我在.Net 3.5,Visual Studio 2012中编译了以下代码.

当数组被分配给我的IReadOnlyCollection时,我期望在该行上出现错误,因为没有从Array定义到我的接口的隐式转换.它编译成功,也不会创建任何运行时错误.

需要注意的注意事项:

  • 没有引用其他IReadonlyCollection.所以它必须使用我的(IReadonlyCollection被添加到.Net4.5并且在早期版本中不存在)
  • 当我将它重命名为IMyCollection时,它不再编译
  • 当我更改名称空间时,它不再编译.

File1.cs:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Collections.Generic
{
    public interface IReadOnlyCollection<T> : IEnumerable<T>, IEnumerable
    {
        int Count
        {
            get;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

File2.cs:

using System.Collections.Generic;

namespace ConsoleApplication1
{
    public class Test
    {
        public Test()
        { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test[] foo = { new Test(), new Test(), new Test() };


            IReadOnlyCollection<Test> bar = foo;

            int count = bar.Count;
        } …
Run Code Online (Sandbox Code Playgroud)

c# arrays .net-3.5 implicit-conversion

6
推荐指数
1
解决办法
142
查看次数

CLR如何在数组上实现IEnumerable <T>?

我意识到数组实现IEnumerable<T>"在运行时".根据数据的MSDN文档:

从.NET Framework 2.0开始,Array类实现System.Collections.Generic.IList<T>,System.Collections.Generic.ICollection<T>以及System.Collections.Generic.IEnumerable<T>通用接口.这些实现在运行时提供给数组,因此,泛型接口不会出现在Array类的声明语法中.

当然,这是正确的.在查看源代码时,Array您会看到它仅实现了非泛型版本IEnumerable.

如果运行下面的代码片段,您将看到泛型Enumerator的类型System.SZArrayHelper+SZGenericArrayEnumerator`1[System.String].

String[] array = new[] { "Apple", "Banana", "Grape" };
IEnumerator enumer = ((IEnumerable<String>)array).GetEnumerator();

// Next line writes: System.SZArrayHelper+SZGenericArrayEnumerator`1[System.String]
Console.WriteLine(enumer.GetType());
Run Code Online (Sandbox Code Playgroud)

我希望有人能够提供一些关于 CLR 如何IEnumerable<T>在运行时实现的见解?实现这一目标的机制是什么?在CLR中是硬编码的还是Array类中有什么东西可以通知CLR动态实现泛型版本?

作为后续工作,我正在阅读"Nutshell中的C#5,0"和第274页,作者声称Array该类必须实现非IEnumerable向后版本的"向后兼容性".有人可以举例说明这种"向后兼容性"的必要性吗?

c# arrays ienumerable

6
推荐指数
0
解决办法
126
查看次数

在数组中自动实现接口

我读了一本书"通过C#第四版CLR".我无法理解一个陈述:

因此,例如,如果您有以下代码行:

FileStream[] fsArray;
Run Code Online (Sandbox Code Playgroud)

那么当CLR创建的FileStream[]类型,它会导致这种类型的自动实现 IEnumerable<FileStream>,ICollection<FileStream>以及 IList<FileStream>接口.此外,该FileStream[]类型也将实现的接口的基本类型: IEnumerable<Stream>,IEnumerable<Object>, ICollection<Stream>,ICollection<Object>, IList<Stream>,和IList<Object>.

我用这段代码测试了这个语句:

FileStream[] fsArray = new FileStream[0];

string s = null;
foreach (var m in fsArray.GetType().GetInterfaces())
    s += m.ToString() + Environment.NewLine;
Run Code Online (Sandbox Code Playgroud)

结果,我有这个:

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]
Run Code Online (Sandbox Code Playgroud)

没有执行IEnumerable<Stream>和其他人!我在某处弄错了吗?或杰弗里里希特犯了错误?

此外,我认为这是无意义的.因为Arrays支持协方差.

c# clr

6
推荐指数
1
解决办法
437
查看次数

使用CLR C++中的数组初始化List <T>?

我想知道为什么这个代码在C++/CLI中不起作用但在C#中该死的很容易?

List<Process^>^ processList = gcnew List<Process^>(
  Process::GetProcessesByName(this->processName)););
Run Code Online (Sandbox Code Playgroud)

错误C2664:'System :: Collections :: Generic :: List :: List(System :: Collections :: Generic :: IEnumerable ^)':无法将参数1从'cli :: array ^'转换为'System :: Collections :: Generic :: IEnumerable ^'

这是我想出来的.做得很好.:)

List<Process^>^ processList = gcnew List<Process^>(
  safe_cast<System::Collections::Generic::IEnumerable<Process^>^>
    (Process::GetProcessesByName(this->processName)));
Run Code Online (Sandbox Code Playgroud)

c# arrays clr c++-cli list

5
推荐指数
1
解决办法
6077
查看次数

T []是否实现了IList <T>?

我有一个类构造函数,它接受一个IList<IElement>参数.

在创建类的新实例时,我能够传递一个IElement[]而不是IList<IElement>那个有意义的东西?

c#

4
推荐指数
1
解决办法
110
查看次数

C#编译器是否对IEnumerable进行了特殊处理?

作为示例,使用String类中的Join()方法.当你在字节数组上调用它时,例如

 byte[] bytes = {3,4,5};
 string str = string.Join(",", bytes);
Run Code Online (Sandbox Code Playgroud)

C#编译器映射加入此签名

 public static String Join<T>(String separator, IEnumerable<T> values);
Run Code Online (Sandbox Code Playgroud)

但是,byte []从类Array中隐式派生,它不是从通用的IEnumerable派生的,而是派生自非通用的IEnumerable,即

 public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable {...}
Run Code Online (Sandbox Code Playgroud)

如果我对我自己的类似于这种情况的接口和类做同样的事情,我将得到预期的编译器错误,因为根据规则,你不能将从接口IA(非通用IEnumerable)派生的类转换为接口IB(来自IA的通用IEnumerable).这意味着C#编译器只需对特定名称IEnumerable进行硬编码.这在哪里解释?

c#

3
推荐指数
1
解决办法
141
查看次数