从采访中回来。我与您分享,欢迎提供一个好的,准确的答案。
目的,你有一个静态方法,这个方法接收你有IList<int>
要取回你可以减去3的值并制作代码。
约束: 原始列表(在主中)有一个堆栈上的引用和堆上的值, 结果必须在与原始列表相同的空间(在堆上)返回(它是一个void方法)。此处显示的解决方案不正确,因为在方法中有一个新指针 在堆栈+堆上创建在方法域中。解决方案?
Bonus:如何更改代码以接收int而不是float,double,....
static void Main(string[] args)
{
IList<int> list = new List<int>() { 9, 3, 10, 6, 14, 16, 20};
CanBeDivedByThree(list);
}
static void CanBeDivedByThree(IList<int> list)
{
list = (from p in list
where p % 3 == 0
orderby p descending
select p).ToList<int>();
}
答案 0 :(得分:8)
这是毫无意义的,因为IList
的内部存储不受您的控制。添加(或可能删除)项可能会重新分配内部数据结构。
它特别没有意义,因为样本中的列表包含 value 类型,当您访问它们时,它们仍会被复制。
最后但并非最不重要的是,它基本上是使用托管语言的全部要点,您不必担心内存(al)位置。这些事情是平台的implementation details。
接受你的奖金问题:没有简单的方法可以实现这一目标。有人可能会认为使用带有类型约束的泛型可以解决这里的问题(类似static void CanBeDivedByThree<T>(IList<T> list) where T : struct
),但问题是C#不支持泛型算法。 C#没有模运算符,可以采用类型为'T'和'int'的泛型参数。
答案 1 :(得分:2)
list.RemoveAll(n => n % 3 == 0);
或
for (int i = list.Count - 1; i >= 0; --i)
{
if (list[i] % 3 != 0)
list.RemoveAt(i);
}
第一种方法仅适用于List<T>
。
可以使它成为模板方法,但是余数操作对浮点数没有多大意义。
答案 2 :(得分:2)
不幸的是,只有List而不是IList才能实现RemoveAll。所以我首先将它作为扩展方法实现。
public static int RemoveAll<T>(this IList<T> list, Predicate<T> match)
{
if (match == null)
throw new ArgumentNullException("match");
int destIndex=0;
int srcIndex;
for(srcIndex=0;srcIndex<list.Count;srcIndex++)
{
if(!match(list[srcIndex]))
{
//if(srcIndex!=destIndex)//Small optimization, can be left out
list[destIndex]=list[srcIndex];
destIndex++;
}
}
for(int removeIndex=list.Count-1;removeIndex>=destIndex;removeIndex--)
{
list.RemoveAt(removeIndex);
}
return srcIndex-destIndex;
}
然后你可以使用:
list.RemoveAll(n => n % 3 != 0);
然后,您可以将重载用于其他类型。不幸的是,你不能(轻松地)使它成为通用的,因为泛型不适用于运算符重载。
答案 3 :(得分:1)
其他人已经覆盖了列表部分 - 这只是奖励位。
您不能使用C#泛型以静态类型的方式执行此操作,但如果您使用的是C#4,则可以使用动态类型执行此操作。例如:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
ShowDivisibleBy3(new List<int> { 1, 3, 6, 7, 9 });
ShowDivisibleBy3(new List<decimal> { 1.5m, 3.3m, 6.0m, 7m, 9.00m });
}
static void ShowDivisibleBy3<T>(IEnumerable<T> source)
{
foreach (dynamic item in source)
{
if (item % 3 == 0)
{
Console.WriteLine(item);
}
}
}
}