Ограничение T на строку и int?

Я создал себе общий класс коллекции, который определяется как это.

public class StatisticItemHits<T>{...}

Этот класс может использоваться только с значениями int и string. Однако это

public class StatisticItemHits<T> where T : string, int {...}

не будет компилироваться. Что я делаю неправильно?

Ответы

Ответ 1

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

Ответ 2

Вы можете сделать StatisticItemHits<T> абстрактным классом и создать два подкласса:

StatisticItemHitsInt : StatisticItemHits<int>{}

StatisticItemHitsString : StatisticItemHits<string>{}

Таким образом, может быть только int и строковое представление StatisticItemHits

Ответ 3

Как говорили другие, вы не можете использовать ограничения типа таким образом. Что вы можете сделать, это специализироваться на вашем базовом типе следующим образом:

public class StatisticItemHits <T> { }

public class StringStatisticItemHits : StatisticItemHits<string> { }

public class IntegerStatisticItemHits : StatisticItemHits<int> { }

Кроме того, поскольку ваш базовый класс является общим, вы не сможете использовать его для полиморфизма. Если вам нужно сделать это, StatisticItemHits реализует интерфейс и использует его для ссылок на экземпляры. Что-то вроде:

public class StatisticItemHits <T> : IStaticticItemHits { }

public interface IStatisticItemHits { }

Ответ 4

Учитывая, что здесь у вас есть только два типа, я бы пошел туда по OO-маршруту и ​​просто имел два класса для этих двух типов.

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

Вы можете ограничить только структуры или типы классов, и я думаю, что должны быть ограничения на числовые или операторские ограничения (например, необходимо поддерживать + =)

Int и строка действительно совсем разные, и, конечно, более разные, чем int и double. Для универсального класса не было бы разумно поддерживать неизменный ссылочный тип строки и тип значения int без поддержки других типов, более похожих на любой из них.

Ответ 5

Невозможно сделать это с помощью "where". Вы не можете сделать "или".

Ответ 6

Вы не можете ограничить его строкой и int из предложения where. Вы можете проверить это в конструкторе, но это, вероятно, не очень хорошее место для проверки. Мой подход состоял бы в том, чтобы специализировать класс и абстрагировать создание класса в шаблон (полу -) factory:

class MyRestrictedGeneric<T>
{
    protected MyRestrictedGeneric() { }


    // Create the right class depending on type T
    public static MyRestrictedGeneric<T> Create<T>()
    {
        if (typeof(T) == typeof(string))
            return new StringImpl() as MyRestrictedGeneric<T>;

        if (typeof(T) == typeof(int))
            return new IntImpl() as MyRestrictedGeneric<T>;

        throw new InvalidOperationException("Type not supported");
    }


    // The specialized implementation are protected away
    protected class StringImpl : MyRestrictedGeneric<string> { }
    protected class IntImpl : MyRestrictedGeneric<int> { }
}

Таким образом вы можете ограничить использование класса только строкой и int внутри вашего класса.

Ответ 7

Просто используйте:

where TSource : IEquatable<string>