列表,不要丢失参考

从采访回来。 我与您分享,欢迎提供一个好的,准确的答案。

目的,你有一个静态方法,这个方法接收一个IList你必须得到你可以除以3的值并制作代码。

约束:原始列表(在main中)有一个堆栈上的引用和堆上的值,结果必须在与原始列表相同的空间(在堆上)返回(它是一个void方法)。 此处显示的解决方案不正确,因为在方法中,在方法域中创建堆栈+堆上的新指针。 方案?

额外奖励:如何更改代码以接收int而不是float,double,….

 static void Main(string[] args) { IList list = new List() { 9, 3, 10, 6, 14, 16, 20}; CanBeDivedByThree(list); } static void CanBeDivedByThree(IList list) { list = (from p in list where p % 3 == 0 orderby p descending select p).ToList(); } 

这是毫无意义的,因为IList的内部存储不在您的控制之下。 添加(或可能删除)项可能会重新分配内部数据结构。

它特别没有意义,因为样本中的列表包含在您访问它们时无论如何都要复制的类型。

最后但并非最不重要的是,它基本上是使用托管语言的全部要点,您不必担心内存(al)位置。 这些东西是平台的实现细节 。

接受你的奖金问题:没有简单的方法来实现这一目标。 有人可能会认为使用带有类型约束的generics可以解决这里的问题(类似于static void CanBeDivedByThree(IList list) where T : struct ),但问题是C#没有(还有?)支持通用算术。 C#没有模运算符,可以采用类型为’T’和’int’的generics参数。

 list.RemoveAll(n => n % 3 == 0); 

要么

 for (int i = list.Count - 1; i >= 0; --i) { if (list[i] % 3 != 0) list.RemoveAt(i); } 

第一种方法仅适用于List

可以使它成为模板方法,但是余数操作对浮点数没有多大意义。

不幸的是,只有List而不是IList才能实现RemoveAll。 所以我首先将它作为扩展方法实现。

 public static int RemoveAll(this IList list, Predicate match) { if (match == null) throw new ArgumentNullException("match"); int destIndex=0; int srcIndex; for(srcIndex=0;srcIndex=destIndex;removeIndex--) { list.RemoveAt(removeIndex); } return srcIndex-destIndex; } 

然后你可以使用:

 list.RemoveAll(n => n % 3 != 0); 

然后,您可以将重载用于其他类型。 不幸的是,你不能(轻松地)使它成为通用的,因为generics不适用于运算符重载。

其他人已经覆盖了列表部分 – 这只是奖励位。

您不能使用C#generics以静态类型的方式执行此操作,但如果您使用的是C#4,则可以使用动态类型执行此操作。 例如:

 using System; using System.Collections.Generic; class Test { static void Main() { ShowDivisibleBy3(new List { 1, 3, 6, 7, 9 }); ShowDivisibleBy3(new List { 1.5m, 3.3m, 6.0m, 7m, 9.00m }); } static void ShowDivisibleBy3(IEnumerable source) { foreach (dynamic item in source) { if (item % 3 == 0) { Console.WriteLine(item); } } } }