6

(オブジェクトとして定義された) は、実行時に任意のタイプのBindingSourceクラス(など) になる可能性があります。汎用拡張機能に渡すことができるように、に変換する必要があります。DataSourceIEnumerableIList<Foo>IQueryable<T>

IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class

これまでのところ、私はこれを持っています:

string order = "Message ASC";
Type thetype = bsTotalBindingSource.DataSource.GetType().GetGenericArguments()[0];
IEnumerable<object> totalDataSource = ((IEnumerable<object>)(bsTotalBindingSource.DataSource));
//Blowing up on this next line with 'System.Linq.Queryable is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.'
MethodInfo asQueryableMethod = typeof(Queryable).MakeGenericType(thetype).GetMethod("AsQueryable", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(IQueryable<>) }, null); 
MethodInfo genericAsQueryableMethod = asQueryableMethod.MakeGenericMethod(thetype);
MethodInfo orderUsingSortExpressionMethod = GetType().GetMethod("OrderUsingSortExpression");
MethodInfo genericUsingSortExpressionMethod = orderUsingSortExpressionMethod.MakeGenericMethod(thetype);
bsTotalBindingSource.DataSource = genericUsingSortExpressionMethod.Invoke(this, new object[] { genericAsQueryableMethod.Invoke(totalDataSource, null), order });

ご覧のとおり、ここでの最終目標は、DataSource から何かを取得し、その RuntimeType をIEnumerable<T>どこTでも取得できるAsQueryable<T>ようにすることIQueryable<T>です。

EDIT私が探している方法を具体的に見つけるために掘り下げた後、私は問題について少し先に進みました。次のようになります。

string order = "Message ASC";
Type thetype = bsTotalBindingSource.DataSource.GetType().GetGenericArguments()[0];
//Returns the AsQueryable<> method I am looking for
MethodInfo asQueryableMethod = typeof(Queryable).MakeGenericType(thetype).GetMethods()[1]; 
MethodInfo genericAsQueryableMethod = asQueryableMethod.MakeGenericMethod(thetype);
MethodInfo orderUsingSortExpressionMethod = typeof(SortExtension)GetType().GetMethods()[0];
MethodInfo genericUsingSortExpressionMethod = orderUsingSortExpressionMethod.MakeGenericMethod(thetype);
bsTotalBindingSource.DataSource = genericUsingSortExpressionMethod.Invoke(this, new object[] { genericAsQueryableMethod
//blows up here with 'Object of type 'System.RuntimeType' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[LogRecordDTO]'.'
.Invoke(bsTotalBindingSource.DataSource, new object[] {thetype}), order });
4

3 に答える 3

6

T の型が不明な場所に変換IEnumerable<T>したいとします。IQueryable<T>

private void Test<T>(IEnumerable<T> x)
{
    var queryableX = x.AsQueryable();
}

注: である必要がありますusing System.Linq

于 2012-08-24T13:10:00.050 に答える
1

最も簡単な方法は、IEnumerable を引数として取り、呼び出したいメソッドにオーバーロード (または拡張メソッドを追加) することだと思います。次に、そこから他のメソッドを呼び出すだけです。これが私の言いたいことの例です。

public class MyTestClass
{
    public void Run()
    {
        List<string> myList = new List<string>() { "one", "two" };

        object myListObject = (object)myList;

        Test(myListObject);
    }

    private void Test(object myListObject)
    {
        Type myGenericType = myListObject.GetType().GetGenericArguments().First();

        MethodInfo methodToCall = typeof(MyTestClass).GetMethods().Single(
            method => method.Name.Equals("GenericMethod") && method.GetParameters().First().Name.Equals("myEnumerableArgument"));

        MethodInfo genericMethod = methodToCall.MakeGenericMethod(myGenericType);

        genericMethod.Invoke(this, new object[] { myListObject });
    }

    public void GenericMethod<T>(IQueryable<T> myQueryableArgument)
    {
    }

    public void GenericMethod<T>(IEnumerable<T> myEnumerableArgument)
    {
        GenericMethod<T>(myEnumerableArgument.AsQueryable());
    }
}
于 2012-08-24T16:02:15.810 に答える
0

私は次のことがうまくいくと思います:

// Get generic type argument for everything
Type theType = bsTotalBindingSource.DataSource
    .GetType().GetGenericArguments()[0];

// Convert your IEnumerable<?>-in-an-object to IQueryable<?>-in-an-object
var asQueryable =
    // Get IEnumerable<?> type
    typeof(IEnumerable<>)
    .MakeGenericType(new[] { theType })
    // Get IEnumerable<?>.AsQueryable<?> method
    .GetMethod(
        "AsQueryable",
        new Type[] { theType },
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.Public)
    // Call on the input object
    .Invoke(bsTotalBindingSource.DataSource, new object[0]);

// Sort this queryable
var asSortedQueryable =
    // Get the YourType<?> generic class your sorting generic method is in?
    // If your class isn't generic I guess you can skip the MakeGenericType.
    typeof(yourtype)
    .MakeGenericType(new[] { theType })
    // Get the OrderUsingSortExpression<?> method
    .GetMethod(
        "OrderUsingSortExpression",
        new Type[] { theType },
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.Public)
    // Call on the IQueryable<?> object
    .Invoke(dataSource, new object[] { order });

// Set this object to the data source
bsTotalBindingSource.DataSource = asSortedQueryable;

免責事項として、私はこれについて非常に明確ではありません. 例えばAsQueryable<T>​​から取得するときIEnumerable<T>、ジェネリック引数を渡す必要がありますか? しかし、あなたがやりたいことは可能であり、熟考が必要であると私信じています。これはおおむね正しいと思います

于 2012-08-24T13:20:40.403 に答える