C#:如何在接口中声明一个方法来返回一个类,该类的类标有[Serializable()]属性?

时间:2009-10-27 15:37:07

标签: c#

在C#中,如何在接口中声明一个方法来返回其类标有[Serializable()]属性的对象?

4 个答案:

答案 0 :(得分:4)

不幸的是,你无法做到这一点。接口签名只能在实现者上强制实质上与类型相关的信息。您要做的是在实现者上强制附加属性信息。这在元数据中无法表示,无法实现。

可以强制实现者返回ISerializable。但是,这对于使用Serializable属性标记的对象不起作用。它们只是可序列化的,但不实现ISerializable

我仍然在加快代码合约的速度,但似乎他们可以通过合同类强制执行。它可能最终只是一个运行时执行。

答案 1 :(得分:3)

你做不到。如果您遇到此问题,可以在运行时尽早使用反射来获取所有类型的列表,并从那些过滤到实现IYourInterface的列表。检查每个属性是否为必需属性,如果找不到则抛出异常。

编辑:更好的检查是确保类型可序列化。 C#编译器使用[Serializable]属性来确定是否使用CLI内部标志serializable标记类型。 not 的类型必须具有[Serializable]属性才能使CLI序列化它。

Type t = ...;
if (typeof(IYourInterface).IsAssignableFrom(t) && !t.IsSerializable)
{
    throw new TypeLoadException(string.Format(
        "The type {0} implements IYourInterface but is not serializable",
        t));
}

尽量避免上述检查,尤其是在生产代码中。如果您是第三方组件提供商,那么明确记录要求并信任您的客户遵循它(并相信他们在内部了解/使用类似的方法,如果他们以后遇到麻烦。)

答案 2 :(得分:0)

这是不可能的。属性用于标记属性,方法和类,以便在通过反射检查编译的代码时可以发现属性。编译器知道在遇到属性时将嵌入属性的属性。但是属性在类型系统之外,因此在接口定义之外。

如果你期望一个可序列化的对象,你必须用反射而不是编译时来验证这个运行时。

答案 3 :(得分:0)

以下代码将编译但我不知道它是否符合您的需求:

public interface Test<T>
    where T : System.Runtime.Serialization.ISerializable
{
    T method();
}

public class TestObject : System.Runtime.Serialization.ISerializable
{

    #region ISerializable Membres

    public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
    {
        throw new NotImplementedException();
    }

    #endregion
}

public class TestClass : Test<TestObject>
{
    #region Test<TestObject> Membres

    public TestObject method()
    {
        throw new NotImplementedException();
    }

    #endregion
}