【问题标题】:Attribute restrictions on C# genericsC# 泛型的属性限制
【发布时间】:2018-02-02 01:19:09
【问题描述】:

我有以下方法声明:

public static bool SerializeObject<T>(string filename, T objectToSerialize){

我想将T 限制为使用[Serializable] 属性修饰的类型。

以下内容不起作用,因为“属性 'System.SerializableAttribute' 在此声明类型上无效。它仅在 'Class、Enum、Struct、Delegate' 声明上有效。”:

public static bool SerializeObject<T>(string filename, [Serializable] T objectToSerialize)

我了解必须为属性设置AttributeUsageAttribute(AttributeTargets.Parameter) 才能使用上述内容,而[Serializable] 属性没有此设置。

有没有办法将T 限制为标有[Serializable] 属性的类型?

【问题讨论】:

  • 你能限制一个接口吗?这似乎是执行此操作的自然方式。

标签: c# generics attributes


【解决方案1】:

有没有办法将T 限制为标有[Serializable] 属性的类型?

不,没有办法使用通用约束来做到这一点。这些限制在规范中有清楚的说明,这不是其中之一。

不过,你可以写一个扩展方法

public static bool IsTypeSerializable(this Type type) {
    Contract.Requires(type != null);
    return type.GetCustomAttributes(typeof(SerializableAttribute), true)
               .Any();
}

然后说

Contract.Requires(typeof(T).IsTypeSerializable());

不,这不是一回事,但这是您能做的最好的事情。对泛型的限制相当有限。

最后,你可以考虑说

where T : ISerializable

同样,不是同一件事,但需要考虑。

【讨论】:

    【解决方案2】:

    很遗憾,不,您不能创建检查属性的通用约束。你能做的最好的就是在运行时实现约束:

    if (!typeof(T).GetCustomAttributes(typeof(SerializableAttribute), true).Any())
    {
        throw new ArgumentException();
    }
    

    【讨论】:

      【解决方案3】:

      您可以简单地抛出一个异常,以便程序员知道它必须是可序列化的。

      像这样:

      public static bool SerializeObject<T>(string filename, T objectToSerialize)
      {
          if(!typeof(objectToSerialize).IsSerializable)
          {
                    throw new Exception("objectToSerialize is not serializable");
          }
      }
      

      【讨论】:

        【解决方案4】:

        不,没有。但是,您可以限制类型以实现 ISerializable,这与使用 SerializableAttribute 的装饰不同。

        【讨论】:

          【解决方案5】:

          没有。属性不是约束,而是添加到元数据的信息。 您可以测试该属性是否已设置:

          If(typeof(T).GetCustomAttributes(typeof(SerializableAttribute), false).Length == 0) {
              throw new ...
          }
          

          布尔参数决定是否考虑继承属性。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-10-16
            • 2016-05-10
            • 2020-08-06
            • 2013-07-31
            • 1970-01-01
            • 2017-12-31
            • 1970-01-01
            相关资源
            最近更新 更多