C# 使用运行时创建的委托和对象

C# 使用运行时创建的委托和对象,c#,linq,reflection,delegates,C#,Linq,Reflection,Delegates,我一直在为这个普遍的概念而挣扎,所以是时候伸出援手了。我有一个LINQ查询,它从SQL中选择字符串列表,然后调用Select并提供一个静态方法,该方法接收字符串并返回一个对象: MyDataContext context = new MyDataContext(); var list = ( from t in context.GetTable<FooTable>() where t.FooType = userProvidedString select t.

我一直在为这个普遍的概念而挣扎,所以是时候伸出援手了。我有一个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();
但是,当我在ctor上调用Invoke时,我仍然会得到一个必须强制转换的对象。我确信这是可以做到的,我只是缺少一些关键概念。请给我一个顿悟!
提前感谢…

这些建设性的评论让我朝着正确的方向前进,下面是我提出的解决方案

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,因为new T只能与无参数构造函数一起使用。这不是很好,因为它是为查询结果集中的每个项调用的

我在创建T和U并调用该方法时所做的所有反射都是我在问题帖子中提到的,希望避免。这个解决方案应该充分说明我的意图,所以如果你知道更干净的方法,请插话


再次感谢你的帮助

我肯定这是可以做到的-你肯定能做到什么?你的问题很不清楚。首先,为什么要使用反射来创建比较器?既然您正在使用反射,为什么您认为反射API会有一种方法返回对新创建对象的强类型引用?反射API如何预先知道您正在创建的对象的类型?请提供一个很好的例子,清楚地说明你的要求。准确地解释代码现在做什么以及您想要什么。您不能将其包装在函数中并传入转换器/比较器吗?i、 e.Func&IConparer paramsAgreeing与上述2条注释-似乎您只想编写独特的方法来接受IComparer,然后在某个地方使用工厂方法来返回适当情况下的实例?e、 甚至不需要反射。很抱歉,没有清晰和精确。应该把所有关于思考的闲话都省略掉。目标是对多个列表项类型使用相同的查询。在上面的示例中,这些类型将是MyClass和MyOtherClass。每个都有一个FromString方法,该方法将在查询结果上调用。然后,将使用与列表项类型对应的比较器生成唯一列表。
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();
}