Взгляните на это, когда я достану то, что находится внутри вашего if
:
public static T GetWordType<T>(string word) where T : System.Enum
{
if (typeof(T) == typeof(ActionType))
{ … }
return ActionType.Cancel;
}
Как видите, вы проверяете, является ли T
ActionType
. Если это , а не , тогда вы возвращаете ActionType.Cancel
, что, очевидно, является ActionType
. Но ваш метод должен возвращать T
, который вы только что доказали , а не как ActionType
.
Так что вместо T
вы на самом деле хотите, чтобы ваш метод возвратил ActionType
во всех случаях, потому что это именно то, что вы делаете:
public static ActionType GetWordType<T>(string word) where T : System.Enum
{
if (typeof(T) == typeof(ActionType))
{
foreach (Word<ActionType> action in actionsList)
{
if (action.synonims.Contains(word))
return action.type;
}
return ActionType.None;
}
return ActionType.Cancel;
}
И в этот момент можно утверждать, что вам даже не нужен универсальный c метод, потому что вы на самом деле мало что делаете с этот параметризованный тип T
, кроме проверки его точного типа.
Обычно плохая идея иметь дело с фактическими возможными типами для T
внутри методов generi c. Это делает ваш метод, который должен быть обобщенным c для всех совместимых типов, хрупким, поскольку вы ищете точные типы, но на самом деле имеете дело с бесконечным числом типов T
, которые вы не можете планировать .
С тех пор вы изменили свой вопрос, и он возвращает ActionType.None
внутри if
и WordType.None
вне условия. Вы все еще возвращаете конкретные типы, поэтому ваш метод не может вернуть T
. И это также не будет работать, потому что ActionType
и WordType
являются отдельными типами, и перечисления не допускают наследования, которое могло бы сделать эту работу для других типов возврата.
Если вы не можете знать тип возврата во время компиляции , тогда вам придется возвращать object
и интерпретировать результат во время выполнения, чтобы увидеть, какое значение это на самом деле.
Если вы действительно имели в виду возвращаемое значение * Если 1046 * будет значением типа enum T
, то, что вы могли бы сделать, всегда возвращать значение по умолчанию для перечисления. Таким образом, ваш метод может быть обобщенным c с пользовательской обработкой для ActionType
:
public static T GetWordType<T>(string word) where T : System.Enum
{
if (typeof(T) == typeof(ActionType))
{
// you know `T` is `ActionType`, so you can cast to `T`:
return (T)(object)ActionType.None;
}
// since you don’t know `T`, you cannot refer to actual values on
// the imaginary enum `T`; you can however use the default value
// (which will be the value 0, by default the first enum value)
return default(T);
}