自定义通用 SetFlag / UnsetFlag 扩展方法
Custom generic SetFlag / UnsetFlag extension methods
出于幼稚的天真,我决定为枚举构建通用的 SetFlag
和 UnsetFlag
扩展方法,这样就没有人需要反复阅读我的代码中的按位运算符:
public static void SetFlag<T>(this T en, T flag) where T : Enum {
en |= flag;
}
和
public static void UnsetFlag<T>(this T en, T flag) where T : Enum
{
en &= ~flag;
}
现在我得到的错误是 operator |=
is not applicable to types T
and T
and operator ~
is not applicable to type T
.
我认为我必须将 T
更改为类型“Enum
with HasFlags
”。这是问题的真正根源吗?我该如何改变它?
这是我的方法。正如我在对该问题的评论中所说,我强烈反对在生产代码中使用此方法:
public static T SetFlag<T>(this T en, T flag) where T : struct, IConvertible
{
int value = en.ToInt32(CultureInfo.InvariantCulture);
int newFlag = flag.ToInt32(CultureInfo.InvariantCulture);
return (T)(object)(value | newFlag);
}
public static T UnsetFlag<T>(this T en, T flag) where T : struct, IConvertible
{
int value = en.ToInt32(CultureInfo.InvariantCulture);
int newFlag = flag.ToInt32(CultureInfo.InvariantCulture);
return (T)(object)(value & ~newFlag);
}
用法:
[Flags]
public enum Flags
{
None = 0, A = 1, B = 2, C = 4
}
Flags flags = Flags.A.SetFlag(Flags.C);
flags = flags.UnsetFlag(Flags.C);
如你所见,我使用了它,每个枚举都实现了 IConvertible
。所以我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为 int
的便捷方法。这样做的副作用是您可以将此方法用于实现此接口的所有其他类型。所以你可以滥用这个方法来做这样的事情:
int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1
出于幼稚的天真,我决定为枚举构建通用的 SetFlag
和 UnsetFlag
扩展方法,这样就没有人需要反复阅读我的代码中的按位运算符:
public static void SetFlag<T>(this T en, T flag) where T : Enum {
en |= flag;
}
和
public static void UnsetFlag<T>(this T en, T flag) where T : Enum
{
en &= ~flag;
}
现在我得到的错误是 operator |=
is not applicable to types T
and T
and operator ~
is not applicable to type T
.
我认为我必须将 T
更改为类型“Enum
with HasFlags
”。这是问题的真正根源吗?我该如何改变它?
这是我的方法。正如我在对该问题的评论中所说,我强烈反对在生产代码中使用此方法:
public static T SetFlag<T>(this T en, T flag) where T : struct, IConvertible
{
int value = en.ToInt32(CultureInfo.InvariantCulture);
int newFlag = flag.ToInt32(CultureInfo.InvariantCulture);
return (T)(object)(value | newFlag);
}
public static T UnsetFlag<T>(this T en, T flag) where T : struct, IConvertible
{
int value = en.ToInt32(CultureInfo.InvariantCulture);
int newFlag = flag.ToInt32(CultureInfo.InvariantCulture);
return (T)(object)(value & ~newFlag);
}
用法:
[Flags]
public enum Flags
{
None = 0, A = 1, B = 2, C = 4
}
Flags flags = Flags.A.SetFlag(Flags.C);
flags = flags.UnsetFlag(Flags.C);
如你所见,我使用了它,每个枚举都实现了 IConvertible
。所以我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为 int
的便捷方法。这样做的副作用是您可以将此方法用于实现此接口的所有其他类型。所以你可以滥用这个方法来做这样的事情:
int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1