使用属性进行通用约束

Cie*_*iel 15 c# generics extension-methods attributes

举个例如..

public interface IInterface { }

public static void Insert<T>(this IList<T> list, IList<T> items) where T : IInterface
{
 // ... logic
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我想知道是否可以使用属性作为约束.如 ...

class InsertableAttribute : Attribute

public static void Insert<T>(this IList<T> list, IList<T> items) where T : [Insertable]
{
 // ... logic
}
Run Code Online (Sandbox Code Playgroud)

显然这种语法不起作用,或者我不会发布问题.但我只是好奇是否可能,以及如何做到这一点.

Pie*_*kel 13

不可以.您只能使用(基础)类和接口作为约束.

但是你可以这样做:

public static void Insert<T>(this IList<T> list, IList<T> items)
{
    var attributes = typeof(T).GetCustomAttributes(typeof(InsertableAttribute), true);

    if (attributes.Length == 0)
        throw new ArgumentException("T does not have attribute InsertableAttribute");

    /// Logic.
}
Run Code Online (Sandbox Code Playgroud)


Wes*_*ser 7

号只能使用类,接口,class,struct,new(),和其他类型的参数作为约束条件.

如果InsertableAttribute指定[System.AttributeUsage(Inherited=true)],那么您可以创建一个虚拟类,如:

[InsertableAttribute]
public class HasInsertableAttribute {}
Run Code Online (Sandbox Code Playgroud)

然后约束你的方法,如:

public static void Insert<T>(this IList<T> list, IList<T> items) where T : HasInsertableAttribute
{
}
Run Code Online (Sandbox Code Playgroud)

然后T,即使它只来自基类,也总是具有该属性.实现类可以通过在自身上指定它来"覆盖"该属性.