【发布时间】:2017-11-02 00:24:02
【问题描述】:
我一直在为这个一般概念而苦苦挣扎,所以是时候伸出手来了。我有一个 LINQ 查询,它从 SQL 中选择一个字符串列表,然后调用 Select 并提供一个获取字符串并返回对象的静态方法:
MyDataContext context = new MyDataContext();
var list = (
from t in context.GetTable<FooTable>()
where t.FooType = userProvidedString
select t.SomeColumn).ToList()
.Select(colValue => MyClass.FromString(colVal))
.ToList();
int unique = list.Distinct(new MyClassComparer()).Count();
我有一些使用相同查询但类型不同的不同“配置文件”。例如,除了 MyClass,我还有 MyOtherClass,它还有一个 FromString 方法,它接受一个字符串参数,但返回一个自身的实例。从查询中取回列表后,我想对其调用 Distinct,提供一个在运行时再次确定的比较器委托。
我在这类事情上经常遇到的问题是构建时的类型。我知道我可以像这样创建比较器:
Type comparerType = Type.GetType(String.Format("MyNamespace.{0}Comparer", userProvidedString));
ConstructorInfo ctor = comparerType.GetConstructor(new Type[] { });
但是当我在 ctor 上调用 Invoke 时,我仍然会得到一个必须强制转换的对象。我确信这是可以做到的,而且我只是缺少一些关键概念。请给我一个顿悟! 提前谢谢...
【问题讨论】:
-
“我确定这可以做到” -- 你确定可以做什么?你的问题很不清楚。你为什么首先使用反射来创建比较器?鉴于您正在使用反射,为什么您认为反射 API 有办法返回对新创建对象的强类型引用?反射 API 应该如何先验地知道您正在创建什么类型的对象?请提供一个很好的minimal reproducible example,清楚地说明您的要求。 准确地解释代码现在做什么以及你想要什么。
-
你不能把它包装在一个函数中并传入一个转换器/比较器吗?即
Func<string>&IConparer<T>参数 -
同意上述 2 cmets - 似乎您只想编写
Distinct()方法来接受IComparer<string>,然后在某处使用工厂方法在适当的情况下返回实例?例如甚至不需要反射。 -
抱歉,不够清晰和精确。应该忽略所有关于反射的漫谈。目标是对多个列表项类型使用相同的查询。在我上面的示例中,这些类型将是 MyClass 和 MyOtherClass。每个都有一个将在查询结果上调用的 FromString 方法。然后将使用与列表项类型对应的比较器生成唯一列表。
标签: c# linq reflection delegates