How can I use interface as a C# generic type constraint?

前端 未结 11 2153
不思量自难忘°
不思量自难忘° 2020-11-27 12:27

Is there a way to get the following function declaration?

public bool Foo() where T : interface;

ie. where T is an interface type

相关标签:
11条回答
  • 2020-11-27 12:35

    You cannot do this in any released version of C#, nor in the upcoming C# 4.0. It's not a C# limitation, either - there's no "interface" constraint in the CLR itself.

    0 讨论(0)
  • 2020-11-27 12:38

    I tried to do something similar and used a workaround solution: I thought about implicit and explicit operator on structure: The idea is to wrap the Type in a structure that can be converted into Type implicitly.

    Here is such a structure:

    public struct InterfaceType { private Type _type;

    public InterfaceType(Type type)
    {
        CheckType(type);
        _type = type;
    }
    
    public static explicit operator Type(InterfaceType value)
    {
        return value._type;
    }
    
    public static implicit operator InterfaceType(Type type)
    {
        return new InterfaceType(type);
    }
    
    private static void CheckType(Type type)
    {
        if (type == null) throw new NullReferenceException("The type cannot be null");
        if (!type.IsInterface) throw new NotSupportedException(string.Format("The given type {0} is not an interface, thus is not supported", type.Name));
    }
    

    }

    basic usage:

    // OK
    InterfaceType type1 = typeof(System.ComponentModel.INotifyPropertyChanged);
    
    // Throws an exception
    InterfaceType type2 = typeof(WeakReference);
    

    You have to imagine your own mecanism around this, but an example could be a method taken a InterfaceType in parameter instead of a type

    this.MyMethod(typeof(IMyType)) // works
    this.MyMethod(typeof(MyType)) // throws exception
    

    A method to override that should returns interface types:

    public virtual IEnumerable<InterfaceType> GetInterfaces()
    

    There are maybe things to do with generics also, but I didn't tried

    Hope this can help or gives ideas :-)

    0 讨论(0)
  • 2020-11-27 12:41

    What you have settled for is the best you can do:

    public bool Foo<T>() where T : IBase;
    
    0 讨论(0)
  • 2020-11-27 12:45

    No, actually, if you are thinking class and struct mean classes and structs, you're wrong. class means any reference type (e.g. includes interfaces too) and struct means any value type (e.g. struct, enum).

    0 讨论(0)
  • 2020-11-27 12:54

    The closest you can do (except for your base-interface approach) is "where T : class", meaning reference-type. There is no syntax to mean "any interface".

    This ("where T : class") is used, for example, in WCF to limit clients to service contracts (interfaces).

    0 讨论(0)
  • 2020-11-27 12:54

    I know this is a bit late but for those that are interested you can use a runtime check.

    typeof(T).IsInterface
    
    0 讨论(0)
提交回复
热议问题