Подтвердить что ты не робот

Перегрузки метода, которые отличаются только общим ограничением

Я столкнулся с некоторой проблемой, и я просто не могу найти хорошую работу.

Я хочу иметь эти 3 перегрузки:

public IList<T> GetList<T>(string query) where T: string
public IList<T> GetList<T>(string query) where T: SomeClass
public IList<T> GetList<T>(string query) where T: struct

Очевидно, что первое ограничение даже не будет компилироваться, так что моя первая проблема. (Я понимаю, я мог бы просто сделать это IList, но я хочу, чтобы тот же синтаксис для трех)

В любом случае причина для всего этого заключается в том, что эти методы являются частью оболочки для выполнения SQL-запросов к базе данных - я хочу иметь возможность возвращать результат в виде списка строк (в случае, если кто-то выбирает столбец varchar) список значений (int, float, whatever) или список классов (эти классы представляют таблицы и, следовательно, содержат несколько столбцов)

Я надеюсь, что эта часть была несколько понятной: -)

В любом случае моя большая проблема заключается в том, что я не могу сделать эти перегрузки, поскольку они используют одно и то же имя и список параметров.

Кроме того, я не могу объединить их в один и тот же метод, так как мне нужно вызвать метод в SomeClass в этой реализации, поэтому, если я не хочу делать какое-то тяжелое типизирование или, что еще хуже, отражение, мне нужно это ограничение.

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

Если некоторые из них немного неясны, не стесняйтесь спрашивать: -)

Edit:

Вот мой текущий код для версии "где T: SomeClass". Я пытаюсь добавить поддержку string/valuetypes к этому текущему коду, поэтому, возможно, мой первоначальный подход просто неверен - любые идеи приветствуются в основном: -)

public IList<TValue> GetList<TValue>(string query) where TValue : DbTable, new()
{
    DataSet dataSet = GetDataSet(query);
    IList<TValue> result = new List<TValue>();

    if (dataSet.Tables.Count > 0)
    {
        foreach (DataRow row in dataSet.Tables[0].Rows)
        {
            TValue col = new TValue();
            col.Fill(row);
            result.Add(col);
        }
    }

    return result;
}

Как вы можете видеть, мне нужен точный тип DbTable, чтобы создать новый конструктор. Fill - абстрактный метод DbTable (который является абстрактным классом).

4b9b3361

Ответ 1

Как вы заметили; для этого нет хороших вариантов. Вы можете рассматривать разные имена (а не перегрузки) - GetStringList и т.д.

Однако, интересно, было бы проще удалить ограничение. Единственная проверка типа с "как" - это не совсем "тяжелый" тип-литье, и это может сэкономить много боли.

Ответ 2

как насчет этого?

public IList<T> GetList<T>(string query) where T : new()
{
  // whatever you need to distinguish, this is a guess:
  if (typeof(T).IsPrimitiveValue)
  {
    GetPrimitiveList<T>(query);
  }
  else if (typeof(T) == typeof(string))
  {
    GetStringList<T>(query);
  }
  else
  {
    GetEntityList<T>(query);
  }

}

private IList<T> GetStringList<T>(string query)

private IList<T> GetPrimitiveList<T>(string query)

private IList<T> GetEntityList<T>(string query)