【发布时间】:2011-06-01 08:23:39
【问题描述】:
我正在尝试为NotOfType 提供一个实现,它具有可读的调用语法。 NotOfType 应该是 OfType<T> 的补充,因此会产生所有 非 类型为 T
我的目标是实现一个可以像OfType<T> 一样调用的方法,就像这个 sn-p 的最后一行:
public abstract class Animal {}
public class Monkey : Animal {}
public class Giraffe : Animal {}
public class Lion : Animal {}
var monkey = new Monkey();
var giraffe = new Giraffe();
var lion = new Lion();
IEnumerable<Animal> animals = new Animal[] { monkey, giraffe, lion };
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Giraffe>();
但是,我无法提出支持该特定调用语法的实现。
这是我迄今为止尝试过的:
public static class EnumerableExtensions
{
public static IEnumerable<T> NotOfType<T>(this IEnumerable<T> sequence, Type type)
{
return sequence.Where(x => x.GetType() != type);
}
public static IEnumerable<T> NotOfType<T, TExclude>(this IEnumerable<T> sequence)
{
return sequence.Where(x => !(x is TExclude));
}
}
调用这些方法如下所示:
// Animal is inferred
IEnumerable<Animal> fewerAnimals = animals.NotOfType(typeof(Giraffe));
和
// Not all types could be inferred, so I have to state all types explicitly
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Animal, Giraffe>();
我认为这两种调用的风格都有很大的缺陷。第一个具有冗余的“类型/类型”构造,而第二个则没有意义(我想要一个既不是动物也不是长颈鹿的动物列表?)。
那么,有没有办法实现我想要的?如果没有,在该语言的未来版本中是否有可能? (我在想也许有一天我们会命名类型参数,或者我们只需要显式提供无法推断的类型参数?)
还是我傻了?
【问题讨论】:
-
如果我觉得这样的框架/共享代码会得到相当多的重用,我只会编写这样的框架/共享代码。您多久需要一次这样的方法,它是否证明成本(考虑设计困难所花费的时间)是合理的?
-
你的两个版本做的事情大不相同。
-
@Lette:第一个也会排除继承的类型。
-
@Merlyn:我下班了,所以没有实际成本。但是,是的,这里可能找不到太多的重用。暂时把它当作一个实验。
-
@SLaks:不错的收获。我没有用比两个级别更深的继承层次结构测试它,但现在我会的。谢谢。但是,这对我的问题的本质没有任何影响,这更多是关于方法签名而不是实现。
标签: c# linq type-inference code-readability