C# 在父/子接口中使用子类型
有没有办法在接口中使用子类型?我正在制作一个序列化接口:C# 在父/子接口中使用子类型,c#,interface,C#,Interface,有没有办法在接口中使用子类型?我正在制作一个序列化接口: interface ISerialize { byte[] Serialize(); ? Deserialize(byte[] serialized); // what would go here? } 序列化时,类应返回表示对象的字节数组,反序列化时,应基于序列化数据返回自身的新类。有没有办法在接口中使用子类型?我宁愿不使用ISerialize作为返回类型,这样就不需要对子类进行强制转换。我还认为泛型不应该是必需的,因
interface ISerialize
{
byte[] Serialize();
? Deserialize(byte[] serialized); // what would go here?
}
序列化时,类应返回表示对象的字节数组,反序列化时,应基于序列化数据返回自身的新类。有没有办法在接口中使用子类型?我宁愿不使用ISerialize作为返回类型,这样就不需要对子类进行强制转换。我还认为泛型不应该是必需的,因为实现的类将只返回它自己的类型
注意:我不是在寻找替代的序列化方法(尽管欢迎您提出建议进行评论),我对这个问题总的来说很好奇
编辑:我知道反序列化应该是无效的,但我想不出这个问题还能适用于其他情况
我用以下代码解决了序列化问题:
interface ISerialize
{
byte[] Serialize();
void Deserialize(byte[] serialized);
}
public static class ISerializeExtensions
{
public static T Deserialize<T>(this T sender, byte[] serialized) where T : ISerialize
{
T ret = default(T);
ret.Deserialize(serialized);
return ret;
}
}
接口ISerialize
{
字节[]序列化();
void反序列化(字节[]序列化);
}
公共静态类ISerializeExtensions
{
公共静态T反序列化(此T发送方,字节[]已序列化),其中T:ISerialize
{
T ret=默认值(T);
反序列化(序列化);
返回ret;
}
}
这克服了需要创建新对象进行反序列化的问题。
不过,我仍然对最初的问题感兴趣。以下是没有泛型就无法实现的原因。假设我有一个类似这样的集合:
List<ISerialize> serialzeObjects = new List<ISerialize>();
ISerialize<object> serializable = new Foo();
public class Foo : ISerialize<Foo>
{
/* ... */
}
如果反序列化
的返回类型可能是实现ISerialize
的任何内容,则编译器无法验证该返回类型。编译器所能做的最好的事情就是说它返回的对象实现了iseralize
。如果以这种方式声明接口,您将得到:
public interface ISerialize
{
byte[] Serialize();
ISerialize Deserialize( byte[] data );
}
您必须强制转换到实现类型,因为在编译时通常无法知道返回类型到底是什么
另一种方法是使用泛型:
public interface ISerialize<T>
{
byte[] Serialize();
T Deserialize( byte[] data );
}
如果Foo
看起来像这样:
List<ISerialize> serialzeObjects = new List<ISerialize>();
ISerialize<object> serializable = new Foo();
public class Foo : ISerialize<Foo>
{
/* ... */
}
这将阻止您执行以下操作:
public class Dog : ISerialize<Cat>
{
}
公共类狗:ISerialize
{
}
但是,正如注释中所指出的,如果
Cat:iseralize
,那么这个约束将对您没有帮助。以下是没有泛型您无法做到这一点的原因。假设我有一个类似这样的集合:
List<ISerialize> serialzeObjects = new List<ISerialize>();
ISerialize<object> serializable = new Foo();
public class Foo : ISerialize<Foo>
{
/* ... */
}
如果反序列化
的返回类型可能是实现ISerialize
的任何内容,则编译器无法验证该返回类型。编译器所能做的最好的事情就是说它返回的对象实现了iseralize
。如果以这种方式声明接口,您将得到:
public interface ISerialize
{
byte[] Serialize();
ISerialize Deserialize( byte[] data );
}
您必须强制转换到实现类型,因为在编译时通常无法知道返回类型到底是什么
另一种方法是使用泛型:
public interface ISerialize<T>
{
byte[] Serialize();
T Deserialize( byte[] data );
}
如果Foo
看起来像这样:
List<ISerialize> serialzeObjects = new List<ISerialize>();
ISerialize<object> serializable = new Foo();
public class Foo : ISerialize<Foo>
{
/* ... */
}
这将阻止您执行以下操作:
public class Dog : ISerialize<Cat>
{
}
公共类狗:ISerialize
{
}
但是,正如注释中所指出的,如果
Cat:iseralize
,那么这个约束对您没有帮助。接口方法不能是静态的。在任何情况下,请考虑:T反序列化(字节[]序列化),其中T:something相关的
(我将作为与IoC连接的工厂提供)。没错,它最初是非静态的,并在未经思考的情况下将其更改为静态中间编辑。接口方法不能是静态的。在任何情况下,请考虑:T反序列化(字节[]序列化),其中T:something相关的
(我将作为与IoC连接的工厂提供)。没错,它最初是非静态的,并在未经思考的情况下将其更改为静态中间编辑。我遇到了类似的问题。在这种特定情况下,您不能使用动态
?(dynamic deserialized=obj.Deserialize(/*…*/);
)您还可以让T
extendiseralize
强制Foo
实现iseralize
,这似乎是可行的。+1-很好的解释-我要指出的唯一一件事是没有办法将T
约束到实现类型-这意味着您可以定义Dog:iseralize
。不确定会有什么危害,但这是一个值得考虑的问题。如斯坦利指出的,WOOPS,<代码>:ISEILIALIG/<代码>仍然不局限于<代码> FoO < /代码>,但是它仍然更安全,因为“<代码> CAT/CODE >也必须实现<代码> ISRIIALITI/<代码>。1因为这是一个解决方法,但是我希望避免任何泛型,以防止实现什么类型的漏洞(特别是对于序列化,这可能会导致崩溃),因此我遇到了类似的问题。在这种特定情况下,您不能使用动态
?(dynamic deserialized=obj.Deserialize(/*…*/);
)您还可以让T
extendiseralize
强制Foo
实现iseralize
,这似乎是可行的。+1-很好的解释-我要指出的唯一一件事是没有办法将T
约束到实现类型-这意味着您可以定义Dog:iseralize
。不确定会有什么危害,但这是一个值得考虑的问题。如斯坦利指出的,WOOPS,<代码>:ISEILIALIG/<代码>仍然不局限于<代码> FoO < /代码>,但是它仍然更安全,因为“<代码> CAT/CODE >也必须实现<代码> ISRIIALITI/<代码>。1因为这是一个解决方法,但是我希望避免任何泛型,以防止在实现的类型中出现漏洞(特别是对于序列化,这可能会导致崩溃)