В настоящее время я экспериментирую с дженериками в C # и придумала для себя следующую задачу:
Учитывая обобщенную функцию f<T>
, проверьте во время компиляции, что T является типом из заданного набора[T1, T2, ..., Tn].Например, если в f<T>
у нас есть
CompileTimeAssert<T>.isContainedIn<TypeList<string, int, bool>>();
, то f<int>
должен скомпилироваться, а f<double>
не должен скомпилироваться.
Я еще не совсем там.Это то, что у меня есть до сих пор:
interface ContainsType<T> {}
class TypeList<T1>: ContainsType<T1> {}
class TypeList<T1, T2>: TypeList<T2>, ContainsType<T1> {}
class TypeList<T1, T2, T3>: TypeList<T2, T3>, ContainsType<T1> {}
class TypeList<T1, T2, T3, T4>: TypeList<T2, T3, T4>, ContainsType<T1> {}
// add longer type lists to taste
class CompileTimeAssert<T>
{
public static void isContainedIn<TypeList>()
where TypeList: ContainsType<T> {}
public static void isContainedIn<TypeList>(TypeList tl)
where TypeList: ContainsType<T> {}
}
Учитывая приведенный выше код, компилируются следующие (как и ожидалось):
// uses first overload
CompileTimeAssert<int>.isContainedIn<TypeList<string, int, bool>>();
var myTypeList = new TypeList<string, bool>();
CompileTimeAssert<string>.isContainedIn(myTypeList); // uses second overload
И следующее не компилируется, как и ожидалось:
CompileTimeAssert<short>.isContainedIn<TypeList<string, int, bool>>();
var myTypeList = new TypeList<string, bool>();
CompileTimeAssert<double>.isContainedIn(myTypeList);
Это все очень мило, но также бесполезно.Было бы гораздо полезнее, если бы можно было сделать следующее:
void f<T>()
{
CompileTimeAssert<T>.isContainedIn<TypeList<string, int, bool>>();
}
, а затем иметь f<int>
компиляцию, а f<double>
приведет к ошибке компиляции.
Увы, f<T>
как указано выше, не компилируется (независимо от вызовов с конкретными типами).Я получаю следующую ошибку (при использовании MonoDevelop в Mac OS X):
Ошибка CS0311: тип TypeList<string,int,bool>' cannot be used as type parameter
'TypeList' in the generic type or method 'CompileTimeAssert<T>.isContainedIn<TypeList>()'.
There is no implicit reference conversion from
TypeList 'в' ContainsType '
I kindЯ понимаю, почему это не работает, но до сих пор я не смог придумать рабочую альтернативу.У кого-нибудь есть идеи о том, возможно ли вообще то, что я хочу, в C #?
Спасибо.