简体   繁体   中英

How to declare an Enum to be used by a generic type?

I would like to declare in a parent abstract class something along the lines of:

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

Which would then be implemented in the child class like:

   public override void RefreshDisplay<RxViewModel>(RxViews view)

Where RxViews is an enumeration and "view" a specific value from that enumeration.

The actual view and Enum from which it came will not be known until run-time.

Can this be done? I appreciate the help.

Edit: I may have asked this wrong. The TView is not an enumeration, but rather a view that inherits from ViewModelBase. (I don't see where this is a duplicate question?) Thanks.

Edit: I'm guessing this was fixed in net 4.5. Any ideas how to work around this in net 4.0?

The constraint type you need to use for generics with an Enum in .NET 4.0 is as follows - note you will need to change your class declaration for this to work correctly:

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

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

You should however also do something similar to the following line in your implementation of the method:

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

The type check is necessary due to not being 100% sure that it's an Enum (tho' Enum implements all those aspects which is why they are used).

You might want to consider rather making the method virtual and including that in the base method implementation.

Note that this code is adapted from the answer available here : Create Generic method constraining T to an Enum

You might use a custom class instead of an enum. The base class could be defined as Views, you inherit it for each TView and provides static instances for each value.

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; } }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM