是否可以创建一个类型必须具有索引器的泛型类/方法?
我的想法是让以下两种扩展方法适用于使用索引器获取和设置值的任何类型,但似乎无法找到任何关于它的内容。只有关于使索引器本身具有通用性的东西,这不是我追求的......
public static T GetOrNew<T>(this HttpSessionStateBase session, string key) where T : new()
{
var value = (T) session[key];
return ReferenceEquals(value, null)
? session.Set(key, new T())
: value;
}
public static T Set<T>(this HttpSessionStateBase session, string key, T value)
{
session[key] = value;
return value;
}
答案 0 :(得分:7)
无法应用泛型类型参数具有索引器(或任何运算符)的泛型约束。您可以做的最好的事情是创建一个具有该限制的接口,并限制泛型参数来实现该接口。
答案 1 :(得分:3)
Servy有它。您不能要求该类型具有索引器,但您可以要求该类型实现公开索引器的接口。 IList
和IDictionary
及其通用对应项是主要的内置接口,它们分别使用整数和字符串索引值来公开索引器。不幸的是,一些内置类型(如HttpSessionState)会自动公开索引器,而不会实现识别它们的接口。
您还可以定义自己的索引接口以应用于您控制的任何类型:
public interface IIndexable<TKey, TVal>
{
TVal this[TKey key]{get;}
}
所以,最好的情况是,你可以实现这些方法的三个重载:
public static TElem GetOrNew<TList, TElem>(this TList collection, int key)
where TList : IList<TElem>, TElem:new()
{
...
}
public static TElem Set<TList, TElem>(this TList collection, int key, TElem value)
where TList: IList<TElem>
{
...
}
public static TVal GetOrNew<TDict, TKey, TVal>(this TDict collection, TKey key)
where TDict : IDictionary<TKey, TVal>, TVal : new()
{
...
}
public static TVal Set<TDict, TKey, TVal>(this TDict collection, TKey key, TVal value)
where TDict : IDictionary<TKey, TVal>
{
...
}
public static TVal GetOrNew<TColl, TKey, TVal>(this TDict collection, TKey key)
where TColl : IIndexable<TKey, TVal>, TVal: new()
{
...
}
public static TVal Set<TColl, TKey, TVal>(this TDict collection, TKey key, TVal value)
where TColl : IIndexable<TKey, TVal>
{
...
}
...这将允许您在具有索引器的对象的第90百分位上使用此方法集(包括Array,实际上用于实现IList)。