如何在C#中将字符串与枚举进行比较

68
string strName = "John";
public enum Name { John,Peter }

private void DoSomething(string myname)
{
case1:
     if(myname.Equals(Name.John) //returns false
     {

     }

case2:
     if(myname == Name.John) //compilation error
     {

     }

case3:
     if(myname.Equals(Name.John.ToString()) //returns true (correct comparision)
     {

     }
}

当我使用.Equals时,它是引用比较,而当我使用==时,它表示值比较。
有没有更好的代码来替代将枚举值转换为ToString()进行比较?因为这会破坏值类型枚举的目的,而且枚举上的ToString()已经被弃用了吗?

3
你为什么要将字符串与枚举值进行比较?完全可以避免这种情况吗? - dlev
尝试将枚举与字符串进行比较是一个不好的想法。 - Security Hound
@SecurityHound 在处理他人的代码库时,这种情况通常是不可避免的。 - Douglas Gaskell
7个回答

74

您可以使用Enum.TryParse()方法将字符串转换为相应的枚举值(如果存在):

Name myName;
if (Enum.TryParse(nameString, out myName))
{
    switch (myName) { case John: ... }
}

3
这比比较每个枚举的 ToString() 值要好得多。 :) - myermian
3
MyEnumValue.ToString()有什么不好的地方? - Heinzlmaen
@Heinzlmaen - ToString() 是可以使用的,但是你需要比较很多次字符串(每一个枚举都要比较),即 nameString.Equals(JohnEnum.ToString())。而且你可能会遇到大小写等问题。使用 Enum.TryParse 可以使用 switch 语句,这在我的看法中更为清晰,而如果你必须转换为小写等,则只需在 Enum.TryParse(nameString.ToLowerInvariant(), out myName) 中执行一次即可。 - HappyGoLucky
TryParse也可以使用3个参数,第二个参数设置为true将在枚举集合上执行不区分大小写的搜索。我几乎从未发现过区分大小写的搜索有用,大多数比较都使用像.ToLower等技巧。 - dbeasy

43
你可以解析字符串值并进行枚举比较。 Enum.TryParse:参见http://msdn.microsoft.com/en-us/library/dd783499.aspx
Name result;
if (Enum.TryParse(myname, out result))
{
    switch (result)
    {
        case Name.John:
            /* do 'John' logic */
            break;
        default:
            /* unexpected/unspecialized enum value, do general logic */
            break;
    }
}
else 
{
    /* invalid enum value, handle */
}

如果你只是比较一个单一的数值:
Name result;
if (Enum.TryParse(myname, out result) && result == Name.John)
{
     /* do 'John' logic */
}
else 
{
    /* do non-'John' logic */
}

9

如果您使用的是.NET4或更高版本,您可以使用Enum.TryParse。而Enum.Parse适用于.NET2及更高版本。

// .NET2 and later
try
{
    switch (Enum.Parse(typeof(Names), myName))
    {
        case John: ... 
        case Peter: ...
    }
}

// .NET4 and later
Name name;
if (Enum.TryParse(myName, out name))
    switch (name)
    {
        case John: ... 
        case Peter: ...
    }

3

由于某些原因,给定的解决方案对我没有起作用。我必须以稍微不同的方式去做:

Name myName;
if (Enum.TryParse<Name>(nameString, out myName))
{
    switch (myName) { case John: ... }
}

希望能对某些人有所帮助 :)

3

2
稍微更加优雅的解决方案是字符串扩展方法:
public static bool Equals(this string enumString, Name value)
{
    if(Enum.TryParse<Name>(enumString, out var v))
    {
        return value == v;
    }

    return false;
}

这样,您可以直接在字符串上使用.Equals(),就像OP的第一个示例中一样。


1
我想你要找的是Enum.Parse()方法。
if(myname.Equals(Enum.Parse(Name.John)) //returns false
 {

 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接