Общие параметры .NET для общих списков - PullRequest
1 голос
/ 02 июня 2009

Под управлением .NET 2.0 у меня есть универсальный метод со следующей подписью:

static listType FillCollection<listType, objType>(IDataReader dr) where listType : ICollection<objType>, new()

это цель - перевести источник данных в коллекцию объектов по моему выбору. Моя проблема, которая не совсем проблема, состоит в том, что, когда я звоню, звонок заканчивается примерно так:

List<MyObject> data = FillCollection<List<MyObject>, MyObject>(dr);

Мне любопытно, есть ли способ избавиться от необходимости указывать MyObject дважды в вызове. В идеале я бы мог указать его только один раз вместе с типом коллекции и поддерживать строгий типизированный характер метода. Добавление другого метода-обертки для абстракции сортировки типа ICollection делает свое дело:

List<MyObject> data = FillList<MyObject>(dr);

static List<objType> FillList<objType>(dr)
{
    return FillCollection<List<objType>, objType>(dr);
}

Но я бы предпочел не иметь метода-обертки для каждой коллекции, которую я хочу использовать.

Может быть, у меня нет выбора в этом вопросе, но если это так, мне это не понравится! ;)

Спасибо!

Ответы [ 5 ]

2 голосов
/ 02 июня 2009

Возможно, стоит попробовать:

static listType FillCollection<objType>(IDataReader dr, ICollection<objType> list)

Это позволит вам вызывать его без указания типа дважды, но вы будете вынуждены создать коллекцию вне FillCollection.

var list = new List<MyObject>();
var data = FillCollection<MyObject>(dr, list);

Возможно, это не то, на что вы надеялись, поскольку вы по-прежнему обращаетесь к MyObject дважды (один раз при создании списка, а другой - в коллекции FillCollection), но я не думаю, что вы сможете избежать этого. без потери строгой печати. ​​

1 голос
/ 02 июня 2009

Вроде того, что упомянул Джозеф, в прошлом я использовал параметры «out» с хорошими результатами, но никогда с одним универсальным типом, полагающимся на другой, без получения или возврата значения этого типа. В любом случае, вы можете сделать что-то подобное, хотя у вас должен быть список objTypes и один объект objType, объявленный вне вызова FillCollection, и FillCollection станет void. Вот как это будет выглядеть, но решать, стоит ли улучшать читабельность, зависит только от вас.

public static void FillCollection<listType, objType>(IDataReader dr, out listType collection, out objType obj) 
    where listType : ICollection<objType>, new() 
    where objType : new()
{
    collection = new listType();
    obj = new objType();

    // Do whatever you do to fill the collection
}

public static void TestFillCollection()
{
    IDataReader dr;
    List<MyObject> myObjects;
    MyObject myObject;

    FillCollection(dr, out myObjects, out myObject);
}
1 голос
/ 02 июня 2009

Лично я не совсем уверен, зачем вам нужен ваш метод для создания нескольких различных реализаций ICollection. Я бы хотел иметь сигнатуру метода следующим образом, просто создать список внутри метода и вернуть его.

static ICollection<T> FillCollection<T>(IDataReader dr) where T : class, new()

Если это не приемлемо, тогда я согласился бы с ответом Джозефа.

1 голос
/ 02 июня 2009

Не могли бы вы использовать var?

1 голос
/ 02 июня 2009

Если вы используете Visual Studio 2008, вы все равно можете ориентироваться на .NET 2.0, но использовать синтаксис C # 3.0. Это означает, что вы можете использовать ключевое слово "var":

var data = FillCollection<List<MyObject>, MyObject>(dr);

Когда вы используете Visual Studio 2005, вам не повезло, я боюсь.

...