基类中的 C# 泛型类型
我正在编写一个具有一组协议缓冲区(使用 protobuf-net)的系统,我想在一个抽象类中定义类似的东西,它们都继承了:
public byte[] GetBytes()
但是,协议缓冲区序列化器需要一个类型参数,是否有一些获取继承类类型的有效方法?
例子:
public byte[] GetBytes()
{
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize<T /* what goes here? */>(stream, this);
return stream.ToArray();
}
}
I'm writing a system that has a set of protocol buffers (using protobuf-net), I want to define something like this in an abstract class they all inherit off:
public byte[] GetBytes()
however, the protocol buffer serealiser requires a type argument, is there some efficient way to get the type of the inheriting class?
Example:
public byte[] GetBytes()
{
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize<T /* what goes here? */>(stream, this);
return stream.ToArray();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就写“T”吧?
然后在你的类声明中:
?
-- 编辑
然后当你继承它时:
Just write "T" right?
and then in your class declaration:
?
-- Edit
And then when you inherit it:
你可以通过反射来做到这一点,但 protobuf-net 已经为你做到了。
只需将您的调用更改为:
这可以通过在运行时通过反射构建通用方法来实现。有关详细信息,请检查代码(第二个方法在这里)。
You can do this via reflection, but protobuf-net did it for you.
Just change your call to:
This works by building the generic method at runtime via reflection. For details, check the code (second method here).
将基类定义为
BaseClass
,然后派生类将 T 替换为序列化器类型DerivedClass
。您还可以指定类型参数的约束,例如
此处< /a> 是您可以应用的约束类型的描述。
Define your base class as
BaseClass<T>
and then your derived classes replace T with the serializer typeDerivedClass<SerializerType>
.You can also specify constraints on the type argument e.g.
Here is a description of the types of constraints you can apply.
实际上,您在这里不需要任何特殊的东西......因为 protobuf-net 尊重继承。如果你有:
那么它就会起作用。为了序列化数据,它总是从基本(契约)类型开始;所以即使你做了
Serializer.Serialize(stream, obj)
它要做的第一件事就是检测它有一个作为契约的基类,然后切换到MyBase< /代码>。在反序列化期间,它将识别正确的派生(具体)类型并使用它,因此您也可以将
Deserialize
与MyBase
一起使用,它将构造一个Foo 或
Bar
取决于原始数据是什么。因此,以下内容基本相同:
和
这里的主要区别在于变量的类型。
You don't actually need anything special here... since protobuf-net respects inheritance. If you have:
then it will work. To serialize the data, it always starts at the base (contract) type; so even if you did
Serializer.Serialize<Foo>(stream, obj)
the first thing it will do is detect that it has a base class that is a contract, and switch toMyBase
. During deserialization it will identify the correct derived (concrete) type and use that, so you can useDeserialize
withMyBase
too, and it will construct aFoo
orBar
depending on what the original data was.Thus the following are largely identical:
and
The main difference here is how the variables are typed.