Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在父/子接口中使用子类型_C#_Interface - Fatal编程技术网

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
extend
iseralize
强制
Foo
实现
iseralize
,这似乎是可行的。+1-很好的解释-我要指出的唯一一件事是没有办法将
T
约束到实现类型-这意味着您可以定义
Dog:iseralize
。不确定会有什么危害,但这是一个值得考虑的问题。如斯坦利指出的,WOOPS,<代码>:ISEILIALIG/<代码>仍然不局限于<代码> FoO < /代码>,但是它仍然更安全,因为“<代码> CAT/CODE >也必须实现<代码> ISRIIALITI/<代码>。1因为这是一个解决方法,但是我希望避免任何泛型,以防止实现什么类型的漏洞(特别是对于序列化,这可能会导致崩溃),因此我遇到了类似的问题。在这种特定情况下,您不能使用
动态
?(
dynamic deserialized=obj.Deserialize(/*…*/);
)您还可以让
T
extend
iseralize
强制
Foo
实现
iseralize
,这似乎是可行的。+1-很好的解释-我要指出的唯一一件事是没有办法将
T
约束到实现类型-这意味着您可以定义
Dog:iseralize
。不确定会有什么危害,但这是一个值得考虑的问题。如斯坦利指出的,WOOPS,<代码>:ISEILIALIG/<代码>仍然不局限于<代码> FoO < /代码>,但是它仍然更安全,因为“<代码> CAT/CODE >也必须实现<代码> ISRIIALITI/<代码>。1因为这是一个解决方法,但是我希望避免任何泛型,以防止在实现的类型中出现漏洞(特别是对于序列化,这可能会导致崩溃)