0

このコード例は、この回答https://stackoverflow.com/a/16491759/98706から取られています

public static Boolean PurgeDataObject(this IDataObject dataObject, Guid uid)
{
    return PurgeDataObjectImpl((dynamic) dataObject, uid);
}

private static Boolean PurgeDataObjectImpl<T>(T dataObject, Guid uid)
    where T : IDataObject
{
    return DataProvider.DeleteDataObject<T>(uid, DataProvider.GetConnection());
}

以下に示すように、実行時に型に基づいて関連する EF エンティティを返し、既存の継承されたコードをクリーンアップしようとする同様の状況があります:(

違いは、関数がIEnumerable<T>

GetFilteredData概念がないTため、コンパイルエラーが発生しますThe type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

    private IEnumerable<T> GetFilteredData(Type entityType, SortedList<string, string> filterList, List<int> weeks)
    {
        return GetFilteredDataImpl((dynamic)entityType, filterList, weeks);
    }

    private IEnumerable<T> GetFilteredDataImpl<T>(T entityType, SortedList<string, string> filterList, List<int> weeks) where T : EntityObject
    {
        var data = _modelContext.CreateObjectSet<T>().AsExpandable();
          // do more filtering and then call .ToList() to return a List<T>
    }
4

1 に答える 1

1

Typeリフレクションを使用しないと、クラスをジェネリックTパラメーターに変換できません。パラメータもメソッドの一部として存在する必要があります。

Jon Skeet は、型の安全性を保証し、ジェネリック コードを簡素化するために、ジェネリックと組み合わせた例による型推論を使用していました。Type残念ながら、リフレクションを使用すると、型の安全性が失われます。

private IEnumerable<EntityObject> GetFilteredData(Type entityType,
                                                  SortedList<string, string> filterList,
                                                  List<int> weeks)
{
    var method = typeof(<class>).GetMethod("GetFilteredDataImpl");
    var generic = method.MakeGenericMethod(entityType);
    return (IEnumerable<EntityObject>)generic.Invoke(this, new[] { filterList, weeks });
}

private IEnumerable<T> GetFilteredDataImpl<T>(SortedList<string, string> filterList,
                                              List<int> weeks)
    where T : EntityObject
{
    var data = _modelContext.CreateObjectSet<T>().AsExpandable();
      // do more filtering and then call .ToList() to return a List<T>
}

ただし、渡すオブジェクトを作成することはできます。

private IEnumerable<EntityObject> GetFilteredData(Type entityType, SortedList<string, string> filterList, List<int> weeks)
{
    var instance = (EntityObject)Activator.CreateInstance(entityType);
    return GetFilteredDataImpl((dynamic)instance, filterList, weeks);
}

private IEnumerable<T> GetFilteredDataImpl<T>(T entityType, SortedList<string, string> filterList, List<int> weeks) where T : EntityObject
{
    var data = _modelContext.CreateObjectSet<T>().AsExpandable();
      // do more filtering and then call .ToList() to return a List<T>
}

これは依然として を返しIEnumerable<EntityObject>ますが、ガベージを生成し、 を と交換しArgumentExceptionていInvalidCastExceptionます。

于 2013-07-18T14:39:46.690 に答える