gpt4 book ai didi

c# - 在父/接口(interface)中使用子类型

转载 作者:太空宇宙 更新时间:2023-11-03 21:28:56 25 4
gpt4 key购买 nike

有没有办法在接口(interface)中使用子类型?我正在制作一个序列化接口(interface):

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;
}
}

这克服了需要创建一个新对象来反序列化的问题。不过,我仍然对原来的问题感兴趣。

最佳答案

这就是为什么没有泛型就不能这样做的原因。假设我有一个看起来像这样的集合:

List<ISerialize> serialzeObjects = new List<ISerialize>();

如果有一种方法可以做你想做的事,你会把什么放在这里:

foreach( var obj in serializeObjects )
{
? deserialized = obj.Deserialize( /* ... */ );
}

编译器无法验证 Deserialize 的返回类型如果它可以是任何实现 ISerialize 的东西.编译器最多只能说它返回的对象实现了 ISerialize。 .如果您以这种方式声明接口(interface),这就是您得到的结果:

public interface ISerialize
{
byte[] Serialize();
ISerialize Deserialize( byte[] data );
}

您必须转换为实现类型,因为通常无法在编译时知道返回类型到底是什么。

另一种方法是使用泛型:

public interface ISerialize<T>
{
byte[] Serialize();
T Deserialize( byte[] data );
}

现在您可以拥有特定的返回类型。但是你在这里确实失去了一些东西。 ISerialize<T>ISerialize<U>不能存储在同一位置,因为接口(interface)在其类型参数方面是不变的。但我们可以为此做点什么:

public interface ISerialize<out T>
{
byte[] Serialize();
T Deserialize( byte[] data );
}

现在我们制作了 ISerialize<T> T 中的接口(interface)协变.这意味着我们可以做这样的事情:

ISerialize<object> serializable = new Foo();

前提是Foo看起来像这样:

public class Foo : ISerialize<Foo>
{
/* ... */
}

所以现在,从某种意义上说,ISerialize<T>接口(interface)尊重其类型参数的继承层次结构。

编辑:如果你想添加一个类只能实现 ISerialize 的约束就其本身而言,这样做是完全有可能的:

public interface ISerialize<out T> where T : ISerialize<T>
{
byte[] Serialize();
T Deserialize( byte[] data );
}

现在这将阻止您执行以下操作:

public class Dog : ISerialize<Cat>
{
}

但是,正如评论中指出的那样 Cat : ISerialize<Cat> ,那么这个约束对你没有帮助。

关于c# - 在父/接口(interface)中使用子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25273766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com