在C#中,如何在接口中声明一个方法来返回其类标有[Serializable()]属性的对象?
答案 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
}