我正在构建一个扩展Enum.Parse概念的函数
所以我写了以下内容:
public static T GetEnumFromString<T>(string value, T defaultValue) where T : Enum
{
if (string.IsNullOrEmpty(value)) return defaultValue;
foreach (T item in Enum.GetValues(typeof(T)))
{
if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
}
return defaultValue;
}
Run Code Online (Sandbox Code Playgroud)
我得到一个Error Constraint不能是特殊类System.Enum.
很公平,但是有一个解决方法允许Generic Enum,或者我将不得不模仿该Parse函数并将类型作为属性传递,这会迫使您的代码出现丑陋的拳击要求.
编辑以下所有建议都非常感谢,谢谢.
已经解决了(我已离开循环以保持不区分大小写 - 我在解析XML时使用它)
public static class EnumUtils
{
public static T ParseEnum<T>(string value, T defaultValue) where T : struct, IConvertible
{
if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
if (string.IsNullOrEmpty(value)) return …Run Code Online (Sandbox Code Playgroud) 我在MSDN上阅读了一篇关于C#中泛型的优秀文章.
我脑子里浮现的问题是 - 我为什么要使用通用约束?
例如,如果我使用这样的代码:
public class MyClass<T> where T : ISomething
{
}
Run Code Online (Sandbox Code Playgroud)
我不能T在这个类中切换所有引用ISomething吗?
使用这种方法有什么好处?
我正在编写一个类,它对C#中的每个原始数字类型进行基本相同类型的计算.虽然实际计算更复杂,但可以将其视为计算多个值的平均值的方法,例如
class Calc
{
public int Count { get; private set; }
public int Total { get; private set; }
public int Average { get { return Count / Total; } }
public int AddDataPoint(int data)
{
Total += data;
Count++;
}
}
Run Code Online (Sandbox Code Playgroud)
现在支持double,float和其他定义operator +和operator /的类的相同操作,我首先想到的只是使用泛型:
class Calc<T>
{
public T Count { get; private set; }
public T Total { get; private set; }
public T Average { get { return Count / Total; } }
public T AddDataPoint(T …Run Code Online (Sandbox Code Playgroud) 更新:请参阅此问题的底部以获取C#解决方法.
嗨,您好,
请考虑以下扩展方法:
public static bool HasFlags<T>(this T value, T flags)
where T : System.Enum
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
您可能知道,这将在编译时抛出一个错误,因为通常不允许继承类System.Enum.问题是使用enum关键字指定的任何枚举实际上都继承自System.Enum,因此上述代码将是仅将扩展方法限制为枚举的理想方法.
现在显而易见的解决方法是使用Enum而不是T,但是你失去了泛型类型的好处:
MyEnum e;
e.HasFlags(MyOtherEnum.DoFunkyStuff);
Run Code Online (Sandbox Code Playgroud)
上面的代码会使用泛型类型抛出编译时错误,而它只能使用Enum类型抛出运行时错误(如果我实现它的话).
是否有任何编译器选项可用于关闭约束检查,还是有其他一些漂亮的方法来做到这一点?
在建议之前,我想说我不会使用where T : struct或者其他一些,从那以后你就可以做一些奇怪的事情了123.HasFlags(456).
我很难理解为什么会出现这个错误...这是你要使用的同样的问题where T : System.Object,但是你有where T : class...为什么没有where T : enum?
C#解决方法
Jon Skeet已经开始研究一个库,该库将带有约束的类编译为a
IEnumConstraint,然后将其替换为System.Enumpost-build.我相信,这是目前最接近解决这个问题的人.看到:
- 代码项目:http://code.google.com/p/unconstrained-melody/
- 博客条目:http://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx
如果此解决方法不可行,则必须将库编写为C++/CLI代码,这不会限制可用于泛型类型约束的内容(请参阅下面的答案中的代码.)
我希望能够做到这样的事情:
class A<T1, T2>
{
public void Call(T1 arg1, T2 arg2)
{
B b = new B();
b.DoSomething(arg1); // determine which overload to use based on T1
b.DoSomething(arg2); // and T2
}
}
class B
{
public void DoSomething(int x)
{
// ...
}
public void DoSomething(float x)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我知道可以使用if/else检查来完成,但这似乎并不优雅,特别是当我有20多种类型可供选择时.