我一直在努力解决这个一般概念,所以是时候伸出援手了。我有一个LINQ查询,从SQL中选择一个字符串列表,然后调用Select并提供一个静态方法,它接收一个字符串并返回一个对象:
HEAD~5
我有一些不同的“配置文件”使用相同的查询但具有不同的类型。例如,除了MyClass之外,我还有一个MyOtherClass,它也有一个FromString方法,它接受一个字符串参数,但返回一个自己的实例。从查询中获取列表之后,我想在其上调用Distinct,提供在运行时再次确定的比较器委托。
我总是遇到这种问题的类型是构建时的类型。我知道我可以像这样创建比较器:
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();
但是当我在ctor上调用Invoke时,我仍然会得到一个必须被投射的对象。我确信这可以做到,而我只是缺少一些关键概念。请给我一个顿悟! 提前谢谢......
答案 0 :(得分:0)
&#34;建设性意见&#34;让我朝着正确的方向前进,这是我想出的解决方案。
public void Foo()
{
string dataType = "MyClass"; // Pretend this string was specified by the user
Type t = Type.GetType(dataType);
Type u = Type.GetType(dataType + "Comparer"); // Implements IEqualityComparer<MyClass>
MethodInfo method = this.GetType().GetMethod("GetUniqueItemCount", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo generic = method.MakeGenericMethod(t, u);
int count = (int)generic.Invoke(this, new object[] { "some data blah blah" });
}
private void GetUniqueItemCount<T, U>(string data) where T : class
where U : IEqualityComparer<T>, new()
{
MyDataContext context = new MyDataContext();
var list = (
from v in context.GetTable<SomeTable>()
select v.SomeColumn).ToList()
.Select(cellValue => Activator.CreateInstance(typeof(T), new object[] { cellValue }) as T)
.ToList();
return list.Distinct(new U()).Count();
}
令人遗憾的是,我不得不使用Activator.CreateInstance因为&#34;新的T()&#34;只能与无参数构造函数一起使用。这不是很好,因为它会在查询结果集中调用每个项目。
我在创建T和U并调用方法时所做的所有反思都是我在帖子中提到的(并希望避免)。这个解决方案应该在这里完全说明我的意图,所以如果你知道一个更清洁的方法,请加入。
再次感谢您的帮助!