如何在.NET 3.5中使用TryParse解析枚举值?

5
我需要使用.NET 3.5,但是我想使用TryParse方法,我知道这个方法属于.NET 4.0。然后我在网上搜索了相关主题,我认为我在[Simon Mourier的答案](https://dev59.com/hHNA5IYBdhLWcg3wH6EW#6161718)中找到了最佳解决方案!所以我创建了一个如下的自己的类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace MyClasses
{

    public class MyEnum
    {
    // here goes all of Simons's code
    }
}

然后我尝试在一个新项目中使用该类,如下所示。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyClasses;

namespace MyEnumerations
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Type in a name: ");
            string userValue = Console.ReadLine();

            MyEnumeration myValue;

            if (MyEnum.EnumTryParse(myValue,userValue, out myValue))
            {
                switch (myValue)
                {
                    case MyEnumeration.Elem1:
                        Console.WriteLine("Elem1 caught!");
                        break;
                    case MyEnumeration.Elem2:
                        Console.WriteLine("Elem2 caught");
                        break;
                    case MyEnumeration.Elem3:
                        Console.WriteLine("Elem3 caught");
                        break;
                    default:
                        Console.WriteLine("Does not compute");
                        break;
                }
            }

            Console.ReadLine();

        }
    }

    enum MyEnumeration
    {
        Elem1,
        Elem2,
        Elem3
    }

}    

但我无法获得使用“EnumTryParse”方法的正确语法:特别是似乎我无法正确传递第一个参数,该参数必须为“Type type”。

事实上,我是C#的新手,我肯定知道我必须缺少某些东西,这将使我在获得正确的语法后头痛不已。 但现在我被卡住了。

感谢任何可能的帮助

2个回答

5

正如错误信息所述,您需要将枚举的类型作为第一个参数传递。您还需要更改myValue的类型以匹配EnumTryParseout参数,因此:

object myValue;
if (MyEnum.EnumTryParse(typeof(MyEnumeration), userValue, out myValue))
{
    MyEnumeration actualValue = (MyEnumeration) myValue;
    ...
}

您可能还想考虑我的Unconstrained Melody项目,它可以实现以下功能:

MyEnumeration myValue;
if (Enums.TryParseName(userValue, out myValue))
{
    // Do stuff
}

或者使用显式类型参数:

MyEnumeration myValue;
if (Enums.TryParseName<MyEnumeration>(userValue, out myValue))
{
    // Do stuff
}

Unconstrained Melody有许多通用方法,包括扩展方法,可以在不涉及装箱和转换的情况下完成所有操作。


但是它给了我两个错误:1)'ChojwaClasses.MyEnum.EnumTryParse(System.Type, string, out object)' 的最佳重载方法匹配有一些无效的参数 2)第三个参数:无法将 'out MyEnumerations.MyEnumeration' 转换为 'out object'。 - user3598756
@user3598756:没错,这告诉你myValue的类型不正确;它需要是object类型才能使用该方法。还有其他选择-您可能想查看我的Unconstrained Melody项目:https://www.nuget.org/packages/UnconstrainedMelody/ - Jon Skeet
谢谢Jon。我也从Thomas那里得到了这个。关于你的Unconstrained Melody项目,我必须说我很惊讶。我刚开始学习#C和VS,既无法掌握大部分术语,也无法理解整个架构。我已经将链接保存在我的收藏夹中,并且将来一定会更深入、更有意识地研究它。 - user3598756
1
@user3598756:你不需要了解太多关于Unconstrained Melody的背景就可以使用它——我在这里添加了一个示例。 - Jon Skeet
谢谢Jon再次提供帮助。我会尽快尝试的! - user3598756

1
< p > EnumTryParse 方法的最后一个参数是 out object,所以您传递的参数必须是类型为 object 的,而不是 MyEnumeration(因为 refout 参数是不变的)。由于这不太方便,我建议您将该方法改为通用方法:

public static bool EnumTryParse<T>(string s, out T value)
{
    value = default(T);
    if (Enum.IsDefined(typeof(T), s))
    {
        value = (T)Enum.Parse(typeof(T), s);
        return true;
    }
    return false;
}

你可以这样调用它:
if (MyEnum.EnumTryParse(userValue, out myValue))

(泛型类型参数会根据myValue的类型自动推断,因此您不需要指定它)

是的,它有效。谢谢。现在我想改变Simon的方法以反映这种模式,即使用“out T value”作为最后一个参数,因为Simon的方法似乎更通用。我会尝试一下。如果您有任何建议,我会考虑的。再次感谢。 - user3598756
@user3598756,你认为Simon的回答更通用的原因是什么? - Thomas Levesque
我还发现了另一种可行的方法(也很冗长!)在http://www.kiwipiet.com/2010/01/my-contribution-to-enumtryparse-methods.html。在那里,你也可以像Simon的代码一样指定大小写敏感或不敏感。 - user3598756
@user3598756,确实,它不处理大小写敏感性。而且现在我想起来,它也不能处理 Flags 枚举。Enum.Parse 方法可以同时处理这两种情况,但 Enum.IsDefined 却不能... - Thomas Levesque
@ThomasLevesque - 我最初编写EnumTryParse的主要原因是为了避免抛出异常(除了标志、大小写不敏感和其他小问题之外),它不仅仅是“以更长的方式完成相同的事情”… - Simon Mourier
显示剩余3条评论

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