Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 自定义泛型SetFlag/UnsetFlag扩展方法_C#_Generics_Enums - Fatal编程技术网

C# 自定义泛型SetFlag/UnsetFlag扩展方法

C# 自定义泛型SetFlag/UnsetFlag扩展方法,c#,generics,enums,C#,Generics,Enums,在我孩子气的天真中,我决定为enum构建通用的SetFlag和UnsetFlag扩展方法,因此没有人需要在我的代码中读取、重新读取、重新读取位运算符: public static void SetFlag<T>(this T en, T flag) where T : Enum { en |= flag; } publicstaticvoidsetflag(这个T en,T标志),其中T:Enum{ en |=旗帜; } 及 publicstaticvoid-unset

在我孩子气的天真中,我决定为enum构建通用的
SetFlag
UnsetFlag
扩展方法,因此没有人需要在我的代码中读取、重新读取、重新读取位运算符:

public static void SetFlag<T>(this T en, T flag)  where T : Enum {
    en |= flag;
}
publicstaticvoidsetflag(这个T en,T标志),其中T:Enum{
en |=旗帜;
}

publicstaticvoid-unset标志(这个T-en,T标志),其中T:Enum
{
en&=~旗;
}
现在我得到的错误是运算符
|=
不适用于类型
T
T
,运算符
~
不适用于类型
T


我想我必须将
T
更改为类型“
Enum
,使用
hasvags
”。这是问题的真正根源吗?我将如何改变这一点?

以下是我的方法。正如我在对问题的评论中所说,我强烈反对在生产代码中使用这种方法:

    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);
    }
如您所见,我利用了它,每个枚举都实现了
IConvertible
。因此,我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为
int
的简便方法。这样做的一个副作用是,您可以对实现此接口的所有其他类型使用此方法。所以你可以滥用这种方法来做这样的事情:

int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1

以下是我的方法。正如我在对问题的评论中所说,我强烈反对在生产代码中使用这种方法:

    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);
    }
如您所见,我利用了它,每个枚举都实现了
IConvertible
。因此,我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为
int
的简便方法。这样做的一个副作用是,您可以对实现此接口的所有其他类型使用此方法。所以你可以滥用这种方法来做这样的事情:

int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1

以下是我的方法。正如我在对问题的评论中所说,我强烈反对在生产代码中使用这种方法:

    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);
    }
如您所见,我利用了它,每个枚举都实现了
IConvertible
。因此,我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为
int
的简便方法。这样做的一个副作用是,您可以对实现此接口的所有其他类型使用此方法。所以你可以滥用这种方法来做这样的事情:

int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1

以下是我的方法。正如我在对问题的评论中所说,我强烈反对在生产代码中使用这种方法:

    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);
    }
如您所见,我利用了它,每个枚举都实现了
IConvertible
。因此,我在这个接口上定义了扩展方法,它还提供了一种将枚举值转换为
int
的简便方法。这样做的一个副作用是,您可以对实现此接口的所有其他类型使用此方法。所以你可以滥用这种方法来做这样的事情:

int a = 0;
a = a.SetFlag(5); // a == 5
a = a.UnsetFlag(4); // a == 1


你没有得到
System.Enum
不允许作为类型参数约束的错误吗?@ThomasLielacher没有,我没有得到这个错误。有趣。您使用的是哪个IDE?我已将您的代码粘贴到Visual Studio 2013项目中,它立即显示一个错误:“Constraint cannot be special class‘System.Enum’”@ThomasLielacher Microsoft Visual Studio Professional 2012 Version 11.0.61030.00 Update 4;Microsoft.NET Framework版本4.5.51209我已经尝试过一点,但我觉得,这不是一种优雅和节省的方式。我设法使这些方法起作用,但感觉不“正确”。如果你知道我的意思。你不知道
System.Enum
不允许作为类型参数约束的错误吗?@ThomasLielacher-no,我不知道这个错误。有趣。您使用的是哪个IDE?我已将您的代码粘贴到Visual Studio 2013项目中,它立即显示一个错误:“Constraint cannot be special class‘System.Enum’”@ThomasLielacher Microsoft Visual Studio Professional 2012 Version 11.0.61030.00 Update 4;Microsoft.NET Framework版本4.5.51209我已经尝试过一点,但我觉得,这不是一种优雅和节省的方式。我设法使这些方法起作用,但感觉不“正确”。如果你知道我的意思。你不知道
System.Enum
不允许作为类型参数约束的错误吗?@ThomasLielacher-no,我不知道这个错误。有趣。您使用的是哪个IDE?我已将您的代码粘贴到Visual Studio 2013项目中,它立即显示一个错误:“Constraint cannot be special class‘System.Enum’”@ThomasLielacher Microsoft Visual Studio Professional 2012 Version 11.0.61030.00 Update 4;Microsoft.NET Framework版本4.5.51209我已经尝试过一点,但我觉得,这不是一种优雅和节省的方式。我设法使这些方法起作用,但感觉不“正确”。如果你知道我的意思。你不知道
System.Enum
不允许作为类型参数约束的错误吗?@ThomasLielacher-no,我不知道这个错误。有趣。您使用的是哪个IDE?我已将您的代码粘贴到Visual Studio 2013项目中,它立即显示一个错误:“Constraint cannot be special class‘System.Enum’”@ThomasLielacher Microsoft Visual Studio Professional 2012 Version 11.0.61030.00 Update 4;Microsoft.NET Framework版本4.5.51209我已经尝试过一点,但我觉得,这不是一种优雅和节省的方式。我设法使这些方法起作用,但感觉不“正确”。如果你知道我的意思。