gpt4 book ai didi

.net - 带有 Enum 的通用 T 并将 T 转换为 Enum

转载 作者:行者123 更新时间:2023-12-04 17:56:44 26 4
gpt4 key购买 nike

我四处搜索,找不到任何这样做的例子,尽管这很有帮助:

Create Generic method constraining T to an Enum

我有一个通用函数,它在 API 中包装了一个函数(我无法触摸)。包装的函数采用 System.Enum 并返回相同的值。我的通用版本在此示例的非精简版本中大大简化了事情。

问题是,我不能从 T 到 System.Enum,或者再返回,因为 T 不受限于 System.Enum(至少这是我的理解)。

以下代码有效,但我很想知道是否有任何隐藏的陷阱或更好的方法,因为我对泛型非常陌生:

using System
using System.Collections.Generic
...

public T EnumWrapper<T>(T enumVar) where T : struct, IFormattable, IConvertible, IComparable
{
if (!typeof(T).IsEnum)
throw new ArgumentException("Generic Type must be a System.Enum")

// Use string parsing to get to an Enum and back out again
Enum e = (Enum)Enum.Parse(typeof(T), enumVar.ToString());
e = WrappedFunction(e);
return (T)Enum.Parse(typeof(T), e.ToString());
}

如果这没问题,那么就以此为例。我找不到这个,至少这是一个可行的解决方法。

附言在这种情况下,性能不是问题。以为我在想弦乐工作可能很慢,我总是对性能技巧感兴趣。

最佳答案

您可以使约束更严格。所有枚举都实现了以下接口(interface) IFormattable , IConvertibleIComparable .这将在很大程度上限制您使用类似于它们的原语、枚举和类。

或者,如果您真的想创建一个只能绑定(bind)到枚举的方法或类,您可以执行以下操作:

    public abstract class InvokerHelper<T> where T : class
{
public abstract R Invoke<R>(R value) where R : struct,T;
}


public class EnumInvoker : InvokerHelper<Enum>
{
public override R Invoke<R>(R value)
{
return (R)WrappedMethod(value);
}
}

它笨重且不能用于扩展方法,但您可以将其设为单例对象,然后只有泛型方法。

或者,您可以在 C++/CLI 中编写代码或 Reflection.Emit它允许您创建可以具有约束 where T:struct,Enum 的类

实际上,您似乎只想采用通用 T 调用一个采用枚举并将其返回为 T 的方法,对吗?

然后以下将起作用。
public static T WrappedMethodInvoker<T>(T value) where T:struct,IComparable,IFormattable,IConvertible
{
Enum e;
if((e = value as Enum) == null)
throw new ArgumentException("value must be an Enum")
object res = WrappedMethod(e);
return (T)res;
}

这更容易一些。首先我们知道 T 是 Enum ,您可以使用 as运算符尝试转换为可空类型(引用类型或可空结构), Enum肯定是。从那里我们可以使用返回类型的协方差, WrappedMethod返回 Enum ,这意味着我们可以将它存储在一个对象中。最后,当您在泛型方法中有一个对象时,您可以在语法上将其强制转换为 T。它可能会失败,但我们知道该方法返回一个相同类型的 Enum 是事实。

有一些成本要知道,因为您总是在装箱和拆箱。包装的方法是通用的吗?

我已经编辑了答案以显示针对您的示例案例修改的第一种技术。它非常简单且类型安全,但您总是必须有一个 EnumInvoker 来执行这些操作。
不幸的是,这两个答案的表现应该差不多,因为如果调用 WrappedMethod 的参数是 Enum,那么它会装箱值。第一种方法的唯一优点是它是强类型的,但据我所知,通用虚拟方法是调用最慢的方法。因此,避免类型检查可能不值得为更轻松的调用付出代价。

关于.net - 带有 Enum 的通用 T 并将 T 转换为 Enum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7508455/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com