使用泛型和简单地将字符串值转换为枚举时将字符串值转换为枚举时的混淆

Posted

技术标签:

【中文标题】使用泛型和简单地将字符串值转换为枚举时将字符串值转换为枚举时的混淆【英文标题】:Confusion when casting string value to enum using generic and simply casting string value to enum 【发布时间】:2019-07-14 02:13:42 【问题描述】:

我正在尝试理解泛型,当我在Generics 上观看 SCOTT ALLEN 的 1 个复数视频时,他展示了丑陋代码与好代码的示例 代码,但我不明白我想在下面提到的东西:

public enum Steps

  Step1,
  Step2,
  Step3

丑陋代码示例:

Steps value = (Steps)Enum.Parse(typeof(Steps),input);

良好的代码和强类型:

public static class StringExtensions

   public static TEnum ParseEnum<TEnum>(this string value)
   
      return (TEnum)Enum.Parse(typeof(TEnum),value);
   


var input = "Step1";
var value = input.ParseEnum<Steps>();
console.writeline(value);

但是在这里我不明白为什么第二个代码很好,因为它也在进行强制转换,并且似乎代码 1 和 2 是相同的,或者我可能没有正确理解为什么第二个代码更好,因为它正在执行相同类型的强制转换。

有人可以解释一下第二个代码是如何强类型的,并且按照作者的说法更好,尽管它与第一个代码 sn-p 进行相同的转换吗?

【问题讨论】:

对我来说,扩展似​​乎更丑陋,因为它意味着你可以将 every 字符串解析为一个你当然不能的枚举。话虽如此,您的问题完全是基于意见的。你应该问作者他有什么更好的代码。 扩展的另一个问题是您可以将任何类型作为泛型类型传递,并且代码将编译,但会在运行时抛出。 (例如input.ParseEnum&lt;SomeClass&gt;() 会抛出) 【参考方案1】:

我认为这是一个不好的例子。我认为第二个代码 sn-p 是“好代码”的唯一原因是它符合 DRY 原则(不要重复自己)。这是通用代码,代码被编写了 100 次,但现在只完成了一次,并且做得很好。

对于泛型部分,这段代码有很多错误。例如,您可以在不是枚举的类型上调用它。而且它并没有真正显示出泛型的好处。一个更简单的例子就可以了。

【讨论】:

我们真的应该回答这个假设某事是好还是坏的问题吗?这不是基于意见的问题吗? 我怀疑这个问题是否可以利用客观答案。我认为是的。 @HimBromBeere 我对此并不完全确定。 OP 说它不是“强类型”,它与第一个版本完全相同。可以客观回答。帕特里克,顺便说一句,答案很好 @CamiloTerevinto 我同意“强类型”部分的回答很简单,因为它完全是错误的。然而,这不是真正的问题,即“为什么它更好”,这意味着它更好,这不能客观地声称。 @HimBromBeere 我只是想从泛型的角度理解第二个代码 sn-p 与第一个代码 sn-p 相比如何强类型和更好【参考方案2】:

良好的代码和强类型

这不是好的代码,没有什么比第一个示例中的强类型了。更重要的是,IntelliSense 会建议我这样做

var name = "@CamiloTerevinto@".ParseEnum<Fruit>();

是有效的,但显然不是。事实上,对于这样的场景,该代码甚至没有 try-catch。

总的来说,第二个 sn-p 只是为了符合 DRY 更好一些,但我不会将其作为扩展方法,也不会将其称为强类型。

【讨论】:

为什么它不是强类型是我想要理解的 @ILove*** 因为 Parse 永远不能被强类型化。强类型意味着您正在使用一个类,因此重命名该类可以修复对它的引用 所以假设问题中提到的代码需要强类型,那么需要做什么?只是为了我对泛型的了解 代码示例没有帮助。比较ArrayList and List&lt;T&gt;。这是一个很好的例子。 @ILove*** 泛型对这个例子没有帮助,这就是问题所在。正如 Patrick 提到的,泛型有助于避免使用 object 而不是类,例如【参考方案3】:

我会说扩展方法在使用时提供了更好的可读性,我猜这就是 Scott Allen 试图展示的示例。他真的说它是更强类型的吗?

DRY 原则是将其放入方法中的另一个好点。

另外我可能会通过检查有效的字符串值来扩展它,例如:

public static TEnum ParseEnum<TEnum>(this string enumValue, bool ignoreCase = true) where TEnum : struct

    if (!Enum.TryParse(enumValue, ignoreCase, out TEnum result))
    
        throw new ArgumentException(
            $"enumValue is not a valid typeof(TEnum).Name",
            typeof(TEnum).Name);
    

    return result;

...但这不是重点。

【讨论】:

感谢您为帮助我所做的努力以及您宝贵的时间。感谢:)

以上是关于使用泛型和简单地将字符串值转换为枚举时将字符串值转换为枚举时的混淆的主要内容,如果未能解决你的问题,请参考以下文章

泛型和枚举

泛型和枚举

使用“加载文件数据”时将真假字符串转换为布尔值

13. 泛型和枚举

泛型和强制转换 - 不能将继承的类强制转换为基类

从字符串转换为具有大量值的 Java 枚举 [重复]