【发布时间】:2023-03-19 05:58:01
【问题描述】:
我创建了一个验证器,用于检查 IList<T> 是否存在重复项。我想出了以下实现:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var bar = new Foo() {Bar = "buzz"};
var list = new List<Foo>() { }; //Foo has a property named Bar of type string
var validator = new Validator<Foo, string>(x => x.Bar); //I have to specify the type of Bar
validator.IsValid(list);
}
}
}
public class Foo
{
public string Bar { get; set; }
}
public class Validator<T, Tkey>
{
private readonly Func<T, Tkey> _keySelector;
public Validator(Func<T, Tkey> keySelector)
{
_keySelector = keySelector;
}
public bool IsValid(IList<T> list)
{
if (list != null && list.Count > 0)
{
if (list.GroupBy(_keySelector).Any(g => g.Count() > 1))
{
return false;
}
}
return true;
}
}
但我不喜欢它必须如何使用:我必须在构建过程中指定 Bar 的类型。
问题是我可以在初始化Validator时以某种方式跳过TKey吗?可以以某种方式推断出来吗?
【问题讨论】:
-
首先,您的代码甚至无法编译,没有无参数构造函数,
IsValid不采用 lambda。 -
我不完全同意这个问题的“标记为重复”。另一篇文章询问 why 类型推断在构造函数中是不可能的。这个问题是如果有另一种方式。工厂方法有哪些(实际上在其他帖子的问题中提到了)
-
所以,记录一下 :) 通过使用扩展方法:
public static class SomeStaticClass { public static Validator<T,TKey> GetValidator<T,TKey>(this IEnumerable<T> list, Func<T,TKey> keyselector) { return new Validator<T,TKey>(keyselector); } }您可以简单地使用:var list = new List<Foo>(); //Foo has a property named Bar of type string var validator = list.GetValidator(x => x.Bar); //compiler knows T (Foo) from the list and TKey from the returned property -
重新开放让我很难过。 duplicate I chose 很好地解释了为什么这是不可能的,并且该问题本身已经提供了一种解决方法:使用静态工厂方法,因为它适用于方法。 “我已经输入了答案”不是重新打开的理由。请作为 Generic Type in constructor 的副本再次关闭。
-
@CodeCaster 回想起来,我同意你的看法。我被 cmets 中的这种代码模糊分心了,因此决定重新打开,以便至少获得一个更好的 that 版本。