Could someone please explain what's the difference between inheriting from ISerializable
interface and declaring your object as [Serializable]
?
I know that in the first case you are have to implement the ISerializable
interface members, while in the second case this work is likely to be done by the C# itself.
But what doesn't make sense to me then is the following behavior:
public void Foo<T>() where T : ISerializable
{
// Whatever
}
Now, if I have some class like this:
[Serializable]
public class Value
{
public String Value { get; set; }
}
And unfortunately I can't call my X.Foo<Value>()
, because the compiler says:
There is no implicit reference conversion from 'Value' to 'System.Runtime.Serialization.ISerializable'
I'm pretty sure it's my misunderstanding of something obvious, so please point out what am I doing wrong.
How do I make the where T : ISerializable
statement work with [Serializable]
class too? Is there a way?
What I'm trying to achieve is the compilation-time error if the supplied type T
is not serializable (by using [Serializable]
or ISerializable
way).
Obviously, my current check handles only the second case, so how do I make it handle both of them?
Serializable
is merely an attribute you place on a class to let classes such as SoapFormatter
know (via reflection) it can be serialized. Decorating a class with an attribute does not make a class implement an interface, which is why the compiler complains in your case. If memory serves, one implements ISerializable
if one wants more control over the serialization process.
To answer your update: there is no way you can put a generic constraint on the presence of an attribute.
The next best thing you can do is throw an exception (obviously at runtime, not at compile-time). For a generic method, it would look something like this:
public void Foo<T>()
{
if (!typeof (ISerializable).IsAssignableFrom(typeof (T))
|| !typeof (T).GetCustomAttributes(true).OfType<SerializableAttribute>().Any())
{
throw new InvalidOperationException(string.Format("Type {0} is not serializable.", typeof (T).FullName));
}
}
For a generic class, you could do this in the static constructor (fails faster):
public class Foo<T>
{
static Foo()
{
if (!typeof(ISerializable).IsAssignableFrom(typeof(T))
|| !typeof(T).GetCustomAttributes(true).OfType<SerializableAttribute>().Any())
{
throw new InvalidOperationException(string.Format("Type {0} is not serializable.", typeof(T).FullName));
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With