Как создать универсальный класс, который принимает 3 типа - PullRequest
0 голосов
/ 13 мая 2010

Я пытаюсь создать универсальный класс, который принимает 3 типа, либо простую строку, IList<string> или IList<OntologyStore>.

public class OntologyStore
{
}

public sealed class jim<T> where T:new()
{
    string J;
    IList<string> X = null;
    IList<OntologyStore> X1 = null;

    public jim()
    {
        if (typeof(T) == typeof(String))
        {
            J = string.Empty;
        }
        if (typeof(T) == typeof(OntologyStore))
        {
            X1 = new List<OntologyStore>();
        }
        if (typeof(T)==typeof(IList))
        {
            X = new List<string>();
        }
    }
}

Я легко могу создать, что вы ожидаете, что работать,

jim<OntologyStore> x1=new jim<jim<OntologyStore>()

как и следовало ожидать, но когда я вставил

jim<string> x2=new jim<string>()

компилятор сообщает, что строка не является типом abtract, что вы ожидаете.

Можно ли создать универсальный класс, экземпляр которого можно создать как класс, содержащий строку, или IList<string>, или IList<OntologyStore>?

Ответы [ 5 ]

1 голос
/ 13 мая 2010

Я думаю, что ваша проблема связана с тем, что класс String не имеет открытого конструктора без параметров, как того требует ограничение "new ()".

1 голос
/ 13 мая 2010

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

0 голосов
/ 13 мая 2010

Если вы пишете универсальный класс и делаете вещи, основанные на типе T, это, как правило, признак того, что это нехорошая ситуация для универсальных шаблонов или вы неправильно строите класс.

В этом случае, похоже, это было бы лучше для использования интерфейса, чтобы дать классам общий тип. Если они в конечном итоге совместно используют какую-то реализацию, используйте базовый класс вместо интерфейса.

0 голосов
/ 13 мая 2010

Вы должны установить

открытый закрытый класс Джим, где T: класс, новый ()

если вы хотите использовать строку также

см. Здесь для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/d5x73970.aspx

0 голосов
/ 13 мая 2010

Вы не можете сделать это напрямую с генериками. Общие ограничения должны указывать один тип, который является ограничением для всех реализаций ... В вашем случае не существует общего базового класса для System.String, IList<String> и IList<OntologyStore>, который является уникальным базовым классом или интерфейсом для них. типы (поскольку System.Object и IEnumerable являются единственными распространенными базовыми типами, я считаю ...)

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

Один из вариантов предотвращения дублирования функциональности - создать базовый класс и иметь 3 фабричных метода, которые создают и возвращают подкласс для определенного типа:

public class Jim
{
    protected Jim() {}

    public Jim Create(string value)
    {
        return new StringJim(value);
    }

    private class StringJim : Jim
    {
        public StringJim(string value) { // ...
        }
    }
    // Do same for IList<string> and IList<OntologyStore>..

    // Add common methods here...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...