Лучшая практика для коллекции общих классов - PullRequest
3 голосов
/ 23 октября 2008

Рассмотрим следующий код:

abstract class SomeClassX<T>
{
  // blah
}

class SomeClassY: SomeClassX<int>
{
  // blah
}

class SomeClassZ: SomeClassX<long>
{
  // blah
}

Мне нужна коллекция SomeClassX , однако это невозможно, поскольку SomeClassX ! = SomeClassX и List > не разрешены.

Поэтому мое решение состоит в том, чтобы SomeClassX реализовал интерфейс и определил мою коллекцию как, где ISomeClassX - это интерфейс:

class CollectionOfSomeClassX: List<ISomeClassX>
{
  // blah
}

Это лучший способ сделать это, или есть лучший способ?

Ответы [ 2 ]

1 голос
/ 23 октября 2008

Лучший вариант, как вы предложили, создать интерфейс ISomeClass и реализовать его. Недавно я решил ту же самую проблему с пользовательскими настройками и системой профилей, которую мы хотели использовать для хранения различных типов данных. Это сводилось к:

public interface IEntry
{
    // ...
    object Value { get; set; }
}

Определенный Entry<Single> может быть создан, поскольку Entry<T> неявно реализовал интерфейс:

public class Entry<T> : IEntry
{
    T Value { get; set; }
    object IEntry.Value { get { return Value; } set { return Value; } }
}

Но когда пришло время IDictionary<string,IEntry>, мы вернулись к приведению экземпляров IEntry к соответствующему типу Entry<T> или свойству Value IEntry к соответствующему типу.

// assume entries is IDictionary<string,IEntry>...
var entry = entries["pizza-weight"];
var weight = (float)entry.Value;

Это, конечно, все имеет смысл, потому что точно так же, как и SomeClass<int>! = SomeClass<long>, верно и 101 * *! = IList<SomeClass<long>>.

1 голос
/ 23 октября 2008

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

...