In C#, how can I declare a method in an interface to开发者_如何学运维 return an object whose class is marked with a [Serializable()] attribute?
You cannot do this unfortunately. Interface signatures can only enforce essentially type related information on an implementor. What you are trying to do is enforce attached attribute information on an implementor. This is not representable in metadata and cannot be achieved.
It would be possible to enforce the implementor to return ISerializable
. However that won't work for objects which are tagged with the Serializable
attribute. They are simply serializable but do not implement ISerializable
.
I'm still getting up to speed on Code Contracts but it seems like something they could enforce with a contract class. It would likely end up being a runtime only enforcement though.
You can't. If you're having a problem with this, early at runtime you can use reflection to get a list of all types, and from those filter down to the ones that implement IYourInterface
. Check each one of those for the required attribute and throw an exception if it's not found.
Edit: A better check is to make sure the type is serializable. The C# compiler uses the [Serializable]
attribute to determine whether or not to mark the type with the CLI internal flag serializable. A type does not have to have the [Serializable]
attribute in order for the CLI to serialize it.
Type t = ...;
if (typeof(IYourInterface).IsAssignableFrom(t) && !t.IsSerializable)
{
throw new TypeLoadException(string.Format(
"The type {0} implements IYourInterface but is not serializable",
t));
}
Try to avoid the above check, especially in production code. If you're a 3rd party component provider, then clearly document the requirement and trust your customers to follow it (and trust them to understand/use a similar method internally if they are having trouble later).
This isn't possible. Attributes are used to flag properties, methods, and classes so that the attribute can be discovered when compiled code is examined by reflection. The compiler knows about attributes to the extent that is will embed an attribute if it encounters one. But attributes are outside of the type system and therefore outside of interface definitions.
If you expecting a serializable object, you'll have to verify this a run time with reflection rather than compile time.
The following code will compile but I don't know if it will match with your needs :
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
}
精彩评论