C#泛型的属性限制

时间:2012-03-28 15:36:28

标签: c# generics attributes

我有以下方法声明:

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

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

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

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

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

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

5 个答案:

答案 0 :(得分:9)

  

有没有办法将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

同样,不一样,但需要考虑。

答案 1 :(得分:1)

不幸的是,不,您无法创建检查属性的通用约束。您可以做的最好的事情是在运行时实现约束:

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

答案 2 :(得分:1)

你可以简单地抛出一个异常,这样程序员就知道它必须是Serializable。

像这样:

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

Boolean参数确定是否要考虑继承的属性。