Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.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# C中Enum.Parse的通用版本#_C#_Generics_Enums - Fatal编程技术网

C# C中Enum.Parse的通用版本#

C# C中Enum.Parse的通用版本#,c#,generics,enums,C#,Generics,Enums,我经常想知道为什么C#还没有实现通用的Enum.Parse 假设我有 enum MyEnum { 价值1, 价值2 } 我希望从XML文件/DB条目创建一个枚举 MyEnum val=(MyEnum)Enum.Parse(typeof(MyEnum),“value1”,true); 难道它就不能像这样实现吗 MyEnum cal=Enum.Parse(“value1”); 这似乎是一个小问题,但似乎是一个被忽视的问题 有什么想法吗?它已经在.NET 4;中实现了。)看一看 MyEnum-c

我经常想知道为什么C#还没有实现通用的Enum.Parse

假设我有

enum MyEnum
{
价值1,
价值2
}
我希望从XML文件/DB条目创建一个枚举

MyEnum val=(MyEnum)Enum.Parse(typeof(MyEnum),“value1”,true);
难道它就不能像这样实现吗

MyEnum cal=Enum.Parse(“value1”);
这似乎是一个小问题,但似乎是一个被忽视的问题


有什么想法吗?

它已经在.NET 4;中实现了。)看一看

MyEnum-cal;
如果(!Enum.TryParse(“value1”,out-cal))
抛出新异常(“value1不是枚举MyEnum的有效成员”);

此外,讨论还包含一些有趣的观点。

尽管C#不允许约束到
System.Enum
,但它在.NET中是允许的,C#可以使用具有此类约束的类型或方法。请参阅Jon Skeet的库,其中包含的代码完全符合您的要求。

并使用问题所需的语法:

MyEnum cal = Toolkit.Parse<MyEnum>("value1");

在使用一些方法进行一些调整的同时,尝试构建类似于初始提案的内容:

MyEnum cal = Enum.Parse<MyEnum>("value1");
MyEnum cal=Enum.Parse(“value1”);
在我看来,这种语法在C#中是不可能的,因为枚举类型被视为不可为null

如果调用“Enum.TryParse”方法传递与枚举项不对应的值, 枚举的默认值将在“out”变量中返回。这就是我们需要测试的原因 首先是“Enum.TryParse”结果,因为只需调用

MyEnum cal;
Enum.TryParse<MyEnum>("value1", out cal);
MyEnum-cal;
Enum.TryParse(“value1”,out-cal);
并且检查“cal”值并不总是给出可靠的结果。

公共类EnumHelper
public class EnumHelper
{
    public static T? TryParse<T>(string text)
        where T: struct
    {
        if (string.IsNullOrEmpty(text))
        {
            return null;
        }

        T r;

        if (Enum.TryParse<T>(text, out r))
        {
            return r;
        }

        return null;
    }
}
{ 公共静态T?TryParse(字符串文本) 其中T:struct { if(string.IsNullOrEmpty(text)) { 返回null; } tr; if(枚举TryParse(文本,out r)) { 返回r; } 返回null; } }
略微修改了@ian boyd答案的版本,使用扩展方法避免在调用中指定静态类名:

MyEnum cal = "value1".Parse<MyEnum>();

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(this String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}
MyEnum cal=“value1.Parse(); /// ///转换一个或多个变量的名称或数值的字符串表示形式 //将更多枚举常量转换为等效枚举对象。 /// ///枚举类型。 ///TEnum类型的对象,其值由值表示 ///枚举类型或值为null。 ///enumType不是System.Enum-或 ///值为空字符串或仅包含空格。-或- ///值是名称,但不是为枚举定义的命名常量之一。 ///值超出enumType的基础类型的范围。 公共静态TEnum解析(此字符串值),其中TEnum:struct { return(TEnum)Enum.Parse(typeof(TEnum),value); } 的通用版本是在.NET Core 2.0中引入的。 所以你可以写:

类程序
{
静态void Main(字符串[]参数)
{            
var e=Enum.Parse(“Value1”);
WriteLine($“枚举值为:{e}”);
}
}
髓鞘
{
价值1,
价值2
}
请记住,这不是“旧的.Net框架(.Net 4.8及以下版本)或任何.Net标准中的内容。您需要将.NET Core>=2(或.NET>=5,因为Microsoft“Core”命名)

自.NET Framework 4.0以来,有一个通用版本。所以你可以这样使用它:

if(Enum.TryParse(“Value2”,out var e2))
{
WriteLine($“枚举值为:{e2}”);
}
或者创建自己的帮助器方法,如:

公共静态类枚举
{
公共静态TEnum解析(字符串值),其中TEnum:struct
{
return(TEnum)Enum.Parse(typeof(TEnum),value);
}
}
...
var e3=EnumUtils.Parse(“Value1”);
当然,在将项目迁移到较新的.NET之前,您可以使用非通用版本。)

var e4=(MyEnum)Enum.Parse(typeof(MyEnum),“Value1”);

该链接指向非泛型的
Enum.Parse
方法。您是想链接到新的
Enum.TryParse
方法吗?有趣的是,他们将其约束为struct,new(),而不是向该语言添加新的枚举约束。有趣的是,他们甚至不需要对该语言设置新的约束-它只是一个无法用C#表示的方法。C#编译器可以遵守这些约束,即使您不能用C#编写它们:)太糟糕的TryParse与非泛型解析一样不方便。请注意:对于
Enum.TryParse
,如果您转换整数的字符串表示形式,即
“2”
,它总是成功的,不考虑int值为
2
的任何目标枚举成员。你必须随后调用结果进行完整验证。骗子,如果没有人先到,我甚至无法插入我自己的库;)通用的
Parse
可以是
TryParse
的包装器,如果
TryParse
返回
false
,则抛出
ArgumentException
。它可以简单地引发异常而不是默认值。与非泛型版本的解析相同。其目的是避免(在可能的情况下)异常处理,这被认为是流控制的反模式(参考)。根据其API规范,Enum.TryParse方法“在解析枚举值的字符串表示形式时,无需进行异常处理。”
public class EnumHelper
{
    public static T? TryParse<T>(string text)
        where T: struct
    {
        if (string.IsNullOrEmpty(text))
        {
            return null;
        }

        T r;

        if (Enum.TryParse<T>(text, out r))
        {
            return r;
        }

        return null;
    }
}
MyEnum cal = "value1".Parse<MyEnum>();

/// <summary>
/// Converts the string representation of the name or numeric value of one or
//  more enumerated constants to an equivalent enumerated object.
/// </summary>
/// <typeparam name="TEnum">An enumeration type.</typeparam>
/// <returns>An object of type TEnum whose value is represented by value</returns>
/// <exception cref="System.ArgumentNullException">enumType or value is null.</exception>
/// <exception cref=" System.ArgumentException"> enumType is not an System.Enum. -or- 
/// value is either an empty string or only contains white space.-or- 
/// value is a name, but not one of the named constants defined for the enumeration.</exception>
/// <exception cref="System.OverflowException">value is outside the range of the underlying type of enumType.</exception>
public static TEnum Parse<TEnum>(this String value) where TEnum : struct
{
   return (TEnum)Enum.Parse(typeof(TEnum), value);
}