【发布时间】:2017-11-28 00:15:35
【问题描述】:
先发布代码然后问我为什么会收到此错误会更容易。
抽象类——数据包
abstract class Packet
{
// base class!
}
我的第一个包
public sealed class FirstPacket : Packet
{
// First packet implementations...
}
另一个数据包
public sealed class AnotherPacket : Packet
{
// Another packet implementations...
}
数据包操作码
public enum OpCode
{
FirstPacket,
AnotherPacket
}
抽象类 - BaseConnection
public abstract class BaseConnection
{
private Dictionary<OpCode, Action<Packet>> _packetHandlers;
public Connection() {
_packetHandlers = new Dictionary<OpCode, Action<Packet>>();
}
}
最后,我的客户
public sealed class Client : BaseConnection
{
public Client() : base() {
// Here will throw the errors...
// CS1503 Argument 2: cannot convert from 'method group' to 'Action<Packet>'
_packetHandlers.Add(OpCode.FirstPacket, OnReceiveFirst);
_packetHandlers.Add(OpCode.AnotherPacket, OnReceiveAnother);
}
public void OnReceiveFirst(FirstPacket packet) {
}
public void OnReceiveAnother(AnotherPacket packet) {
}
}
根据this 的回答,派生类是其基类的实例,不涉及强制转换。
在我的代码中,如果 FirstPacket 和 AnotherPacket 是 Packet,为什么我必须使用 lambda 进行“转换”?
public sealed class Client : BaseConnection
{
public Client() : base() {
// This works...
_packetHandlers.Add(OpCode.FirstPacket, p => { OnReceiveFirst((FirstPacket)p); });
_packetHandlers.Add(OpCode.AnotherPacket, p => { OnReceiveAnother((AnotherPacket)p); });
}
public void OnReceiveFirst(FirstPacket packet) {
}
public void OnReceiveAnother(AnotherPacket packet) {
}
}
这对我来说没有意义。
【问题讨论】:
-
因为你要走另一条路。
p是Packet并且您的方法需要派生类型。您可以将FirstPacket或AnotherPacket对象透明地传递给期望Packet的方法,但反之则不行。例如,您可以将Giraffe对象传递给期望Animal的方法,但不能将Animal对象传递给期望Giraffe的方法而不进行强制转换。