以下通用静态方法采用字符串并返回枚举。
很好忽略大小写,因为我将ignoreCase参数设置为true。
但是,我还想测试枚举是否存在,但执行此操作的enum.IsDefined方法似乎没有 ignoreCase 参数。
如何测试是否定义了枚举并且同时忽略了这种情况?
using System;
namespace TestEnum2934234
{
class Program
{
static void Main(string[] args)
{
LessonStatus lessonStatus = StringHelpers.ConvertStringToEnum<LessonStatus>("prepared");
ReportStatus reportStatus = StringHelpers.ConvertStringToEnum<ReportStatus>("finished");
Console.WriteLine(lessonStatus.ToString());
Console.WriteLine(reportStatus.ToString());
Console.ReadLine();
}
}
public static class StringHelpers
{
public static T ConvertStringToEnum<T>(string text)
{
if (Enum.IsDefined(typeof(T), text)) //does not have ignoreCase parameter
return (T)Enum.Parse(typeof(T), text, true);
else
return default(T);
}
}
public enum LessonStatus
{
Defined,
Prepared,
Practiced,
Recorded
}
public enum ReportStatus
{
Draft,
Revising,
Finished
}
}
答案 0 :(得分:36)
public enum MyEnum
{
Bar,
Foo
}
class Program
{
static void Main(string[] args)
{
var containsFoo = Enum.GetNames(typeof(MyEnum)).Any(x => x.ToLower() == "foo");
Console.WriteLine(containsFoo);
}
}
答案 1 :(得分:29)
除了@ Darin的回答,在.NET 4.0中,Enum类型现在有一个TryParse方法:
MyEnum result;
Enum.TryParse("bar", true, out result);
要记住的重要一点是,Parse与TryParse的行为存在根本区别。解析方法会抛出异常。 TryParse方法不会。了解您是否可能尝试解析许多项目非常重要。
答案 2 :(得分:5)
改为使用Enum.TryParse:
T val;
if(Enum.TryParse(text, true, out val))
return val;
else
return default(T);
答案 3 :(得分:5)
我正在使用Compact Framework 3.5,并且:
Enum.TryParse
......不存在。确实有:
Enum.IsDefined
..但是它不支持 ignoreCase 参数。 我想要两全其美,所以想出了这个(作为辅助方法)......
public bool TryParse<TEnum>(string value, bool ignoreCase, ref TEnum result) where TEnum : struct
{
bool parsed;
try
{
result = (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase);
parsed = true;
}
catch { }
return parsed;
}
HTH
答案 4 :(得分:5)
正如其他人所说的那样,你可以简单地使用Enum.TryParse
。
但是,如果您想要一个更强大/一般的转换,允许您转换的不仅仅是字符串,那么您还需要使用Enum.IsDefined
,不幸的是,正如您所发现的那样,不是强>不区分大小写。
Enum.TryParse
(可以)不区分大小写。但不幸的是,它允许超出范围的整数通过!
所以解决方案是将它们一起使用(顺序很重要)。
我写了一个扩展方法就是这么做的。它允许从string,int / int?和任何其他Enum / Enum转换?像这样输入:
string value1 = "Value1";
Enum2 enum2 = value1.ParseToEnum<Enum2>();
Debug.Assert(enum2.ToString() == value1);
Enum1 enum1 = Enum1.Value1;
enum2 = enum1.ParseToEnum<Enum2>();
Debug.Assert(enum2.ToString() == enum1.ToString());
int value2 = 1;
enum2 = value2.ParseToEnum<Enum2>();
Debug.Assert(enum2.GetHashCode() == value2);
这是该方法的核心。这是回答您问题的转换部分。变量value
的类型为object
,因为我有“重载”,它将不同的类型作为主要输入(见上文),但您可以使用{{1}类型的变量执行此操作如果这就是你想要的那么就好了(显然将string
改为value.ToString()
)。
value
我的扩展方法还有很多......它允许你指定默认值,处理超出范围的int就好了,并且完全不区分大小写。如果有人感兴趣,我可以发布更多内容。
答案 5 :(得分:1)
enum DaysCollection
{
sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
public bool isDefined(string[] arr,object obj)
{
bool result=false;
foreach (string enu in arr)
{
result = string.Compare(enu, obj.ToString(), true) == 0;
if (result)
break;
}
return result;
}
private void button1_Click(object sender, EventArgs e)
{
object obj = "wednesday";
string[] arr = Enum.GetNames(typeof(DaysCollection)).ToArray();
isDefined(arr,obj);
}
答案 6 :(得分:0)
public static T ConvertStringToEnum<T>(string text)
{
T returnVal;
try
{
returnVal = (T) Enum.Parse( typeof(T), text, true );
}
catch( ArgumentException )
{
returnVal = default(T);
}
return returnVal;
}
答案 7 :(得分:0)
使文本与枚举字符串相同:
enum FileExts
{
jpg,
pdf
}
if (Enum.IsDefined(typeof(T), text.tolower())) //does not have ignoreCase parameter
return (T)Enum.Parse(typeof(T), text, true);
else
return default(T);
答案 8 :(得分:0)
我有一个类似的问题,并使用public class GenericControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
// This is designed to run after the default ControllerTypeProvider,
// so the list of 'real' controllers has already been populated.
foreach (var entityType in EntityTypes.Types)
{
var typeName = entityType.Name + "Controller";
if (!feature.Controllers.Any(t => t.Name == typeName))
{
// There's no 'real' controller for this entity, so add the generic version.
var controllerType = typeof(GenericController<>)
.MakeGenericType(entityType.AsType()).GetTypeInfo();
feature.Controllers.Add(controllerType);
}
}
}
}
(不区分大小写的标记设置为.Enum.TryPase
)和true
的组合。请考虑以下内容作为助手类的简化:
Enum.IsDefined
虽然我们正在使用它,但由于辅助类是静态的并且方法是静态的 - 我们可以在public static class StringHelpers
{
public static T ConvertStringToEnum<T>(string text)
{
T result;
return Enum.TryParse(text, true, out result)
&& Enum.IsDefined(result.ToString())
? result
: default(T);
}
}
上将其作为扩展方法。
string
在这里,我创建了一个.NET Fiddle
,清楚地证明了这一点。
答案 9 :(得分:0)
首先使用Enum.TryParse
方法获取类型为T
的对象,然后将该对象传递给Enum.IsDefined
方法:
private static T ConvertStringToEnum<T>(string stringValue) where T : struct
{
if (System.Enum.TryParse(stringValue, out T result))
{
if (System.Enum.IsDefined(typeof(T), result) || result.ToString().Contains(","))
return result;
throw new System.Exception($"{stringValue} is not an underlying value of the {typeof(T).FullName} enumeration.");
}
throw new System.Exception($"{stringValue} is not a member of the {typeof(T).FullName} enumeration.");
}