通用参数上的属性有什么用途?

17

在类或方法的通用参数上放置属性是有效的(即编译并运行):

public class MyClass<[My] T>
{
    private void MyMethod<[My] T>()
    {}
}

public class MyAttribute : Attribute
{}

我从未见过这种用法,也很难想出为什么你会想要这样做。

这只是语言规范的一个怪癖/副作用,还是将属性放在这个位置有一个有效/有用的理由?


6
那些是通用的参数,而不是限制条件。 - SLaks
4
我不知道可以将属性应用于泛型参数。太酷了 :) - Antoine Aubry
我从未见过这个,非常有趣,谢谢!现在如果我能真正找到一个用途...编辑:您可以在任何类型的方法上使用参数属性 - 不仅仅是通用的。这让我大开眼界。 - RichK
@RichK:对于普通参数,它甚至有用处,我在Interop中看到过[out] - H H
2个回答

13

与任何结构一样,属性都有其用处;它们提供元数据,可供反射或其他后处理器使用以执行各种操作。例如,您可能拥有一个AOP系统,该系统使用类型参数上的属性来应用某些运行时约束,否则无法表达。我不确定是否有任何实际使用这些属性来执行任何操作的系统,但没有理由禁止它们作为元数据。


我曾考虑过反射的情况,因为我在应用程序中使用相同的方法来标记类,但我仍然很难想到这个特定功能的场景。 - adrianbanks
4
adrianbanks: Dan的回答是准确的。例如,我曾经编写了一个工具,它可以处理带有[DelegateConstraint]或[EnumConstraint]的通用参数,将它们的约束更改为Delegate或Enum,以克服C#的限制。 - Jb Evain
@Jb Evain:我以前也做过同样的事情!哈哈。 - Cheng Chen
我也发现泛型参数对于限制枚举类型非常有用-它可以使在Windows Forms项目中填充ComboBoxes变得更加容易和不容易出错: class MyComboBoxWithEnumValues<[EnumConstraint] TEnum>if (!typeof(TEnum).IsEnum) throw new Exception(string.Format("{0} isn't an enumeration, stupid!", typeof(TEnum).FullName)); 简单得多。 - Michael Hoffmann

1

我相信某些AOP狂热者会找到使用属性装饰泛型参数的有效理由,但我确实想不出任何理由。试试这个:

typeof(MyClass<>).GetGenericArguments().GetCustomAttributes().OfType<MyAttribute>();

如果这个Enumerable有任何元素,那么就可以访问你放在类的泛型参数上的属性。如果没有,那么你就不能访问,因此在代码库中的任何其他类中访问数据是毫无意义的。然而,它们仍然可以在实例化时运行代码,并且当泛型类进入作用域时由运行时实例化,允许你在属性本身中执行面向方面的逻辑。具体是什么以及它与直接装饰泛型类或方法有何不同,留给那些比我更崇拜AOP的人来练习。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接