【问题标题】:How to declare an Enum to be used by a generic type?如何声明一个泛型类型使用的枚举?
【发布时间】:2025-12-18 16:15:02
【问题描述】:

我想在父抽象类中声明如下内容:

  public abstract void RefreshDisplay<TView>(Enum value);

然后将在子类中实现,例如:

   public override void RefreshDisplay<RxViewModel>(RxViews view)

其中 RxViews 是一个枚举,并从该枚举中“查看”特定值。

实际的视图和它来自的枚举要到运行时才能知道。

这可以吗?感谢您的帮助。

编辑:我可能问错了。 TView 不是枚举,而是继承自 ViewModelBase 的视图。 (我看不出这是一个重复的问题?)谢谢。

编辑:我猜这在 net 4.5 中已修复。任何想法如何在 net 4.0 中解决这个问题?

【问题讨论】:

  • 为什么不使用两种泛型类型,一种用于 viewModel,另一种用于 Enum,如下所示: public abstract void RefreshDisplay(TEnum value) where TEnum : Enum;跨度>
  • 您可以使用自定义类而不是枚举。基类可以定义为 Views,您可以为每个 TView 继承它并为每个值提供静态实例。
  • 很难说没有。不要对类型安全太过分了;让一切都合适可能是一种很好的心理锻炼,但有时向上转换和断言更具可读性和实用性,而且类型理论本身也有一些松散的边缘。
  • 也可以考虑使用 java 风格的枚举:*.com/a/469315/171121

标签: c# generics


【解决方案1】:

.NET 4.0 中带有Enum 的泛型需要使用的约束类型如下 - 请注意,您需要更改类声明才能使其正常工作:

public abstract class BaseClass<TView, TEnum> 
    where TView: ViewModelBase
    where TEnum : struct,  IComparable, IFormattable, IConvertible
{

    public abstract void RefreshDisplay<TView, TEnum>(TEnum value);
}

但是,您还应该在方法的实现中执行类似于以下行的操作:

if (!typeof(TEnum).IsEnum) { throw new ArgumentException("TEnum must be an enumerated type"); }

类型检查是必要的,因为不能 100% 确定它是 Enum(尽管 Enum 实现了所有这些方面,这就是使用它们的原因)。

您可能需要考虑创建 virtual 方法并将其包含在基本方法实现中。

请注意,此代码改编自此处提供的答案:Create Generic method constraining T to an Enum

【讨论】:

  • 他如何在覆盖方法中指定泛型类而不是子类?
  • 他的班级会变成class ViewModelBase&lt;TView, TEnum&gt;
  • 抽象方法不能包含正文!
【解决方案2】:

您可以使用自定义类而不是枚举。基类可以定义为视图,您可以为每个 TView 继承它并为每个值提供静态实例。

public abstract class A
{
    public abstract void RefreshDisplay<TView>(Views<TView> value);
}

public abstract class Views<TView>
{
    internal Views() {} //Used to disallow inheriting from outside, not mandatory...

    //You can add other methods/properties to allow processing in RefreshDisplay method
}

public sealed class RxViews : Views<TView>
{
    private RxViews() {}

    private static readonly RxViews myFirstRxView = new RxViews();
    public static RxViews MyFirstRxView { get { return myFirstRxView; } }
}

【讨论】: