Ограничение 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>