【问题标题】:Make sure that target inherit some interface for custom attribute确保目标继承一些自定义属性的接口
【发布时间】:2012-02-05 14:06:58
【问题描述】:

我需要创建一些自定义属性,用于我的反射函数。

这是我所看到的用例:

  • 用户创建了一些类并用我的特殊属性标记它(例如[ImportantAttribute]
  • 然后用户使用我的库中的函数执行某些操作。这些函数找到具有 [ImportantAttribute] 的类并对其进行处理

主要问题是我的库中的函数期望,标记有 [ImportantAttribute] 的类继承我的接口(例如 IMyInterface

有没有办法让用户知道他是否用 [ImportantAttribute] 标记了他的类并且在编译期间而不是在运行时忘记继承 IMyInterface。以某种方式指定此属性仅适用于继承 IMyInterface 的类。

与属性和字段的属性相同。

【问题讨论】:

  • 为什么用户不能从 IMyInterface 显式继承创建他的类?即,“ImportantAttribute”给聚会带来了什么?
  • @Garry Vass 这个属性告诉我的函数,它必须聚合标记的类。用户可以创建一些继承 IMyInterface 的类,并且他不希望我的函数聚合它。但是所有标有 ImportantAttribute 的类都必须实现 IMyInterface

标签: c# reflection attributes custom-attributes


【解决方案1】:

有没有办法让用户知道他是否用 [ImportantAttribute] 期间忘记继承 IMyInterface 编译,不在运行时

简单的回答:,这是不可能的。不在编译时。您可以使用反射在运行时检查这一点。

您可以在编译时对属性做的最好的事情(除了一些特殊的系统属性,例如 Obsolete,但它们直接合并到编译器中)是使用 [AttributeUsage] 属性指定它们的用法。

【讨论】:

  • 非常感谢您的回答,首先。我知道,我可以指定属性的用法(用于类或属性),但尽量使我的库最易于使用。编译我们的朋友和我们的使命——给他尽可能多的信息。在编译时出错比在运行时出错更舒服。
  • @Yavanosta,我同意提供编译时安全性而不是运行时安全性会更好,但在这种情况下,您不应该使用属性,因为它们在运行时通过反射工作。所以你没有安全感。也许你应该重新考虑你的设计。
【解决方案2】:

我已经在我构建的几个框架中使用了您提到的策略,并取得了很大的成功。一个这样的例子是为插件基础设施提供元数据:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class PluginAttribute : Attribute
{
    public string DisplayName { get; set; }
    public string Description { get; set; }
    public string Version { get; set; }
}

public interface IPlug
{
    void Run(IWork work);
}

[Plugin(DisplayName="Sample Plugin", Description="Some Sample Plugin")]
public class SamplePlug : IPlug
{
    public void Run(IWork work) { ... }
}

这样做可以让我找出有关插件的信息,而无需实例化它们并读取元数据属性。

根据我这样做的经验,我发现强制满足这两个要求的唯一方法是执行运行时检查并确保它是 boldblinking 在文档中。它远非最佳,但它是可以做到的最好的(我发现)。再说一次,我确信有更好的方法来处理这个问题,但到目前为止,这对我来说非常可靠。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-25
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2012-03-26
    • 2017-05-12
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多