类似于"using"的东西,它将创建一个对象并在完成后对其调用方法,但让我在两者之间做我想做的事情



我正在使用Lidgren,对于我制作的每种新类型的消息,我最终都编写了相同类型的代码。我正在创建一个NetOutgoingMessage的实例,在它上面运行各种赋值调用,然后在我完成后发送它。创建和发送是相同的,所以我想写一个包装器来为我做这个,但它是一个sealed类,而不是IDisposable。我所做的类似于:

NetOutgoingMessage om = server.CreateMessage();
om.Write(messageType);
om.Write(data1);
om.Write(data2);
server.SendMessage(om, server.Connections, NetDeliveryMethod.UnreliableSequenced, 0);

我想这样做:

using(AutoNetOutgoingMessage om(server, messageType, NetDeliveryMethod.UnreliableSequenced))
{
    om.Write(data1);
    om.Write(data2);
}

显然我不能做using,所以有没有其他常见的方法,如果实现这样的功能?我不是在寻找一个非常复杂的解决方案,因为这对我来说只是关于可维护性,所以我对每个消息都重复我的代码没有问题。但是我很好奇是否有一个我不知道的有趣的c#技巧

是的,您可以通过接收包含自定义操作的委托并在需要时调用该委托来轻松地在某些调用之间强制执行这种时间关系。

下面是一个例子:

void MyMethod(Server server, Action<NetOutgoingMessage> action)
{
    NetOutgoingMessage om = server.CreateMessage();
    action(om);
    server.SendMessage(om, server.Connections, NetDeliveryMethod.UnreliableSequenced, 0);     
}

这样写:

MyMethod(server, om => {
    om.Write(data1);
    om.Write(data2);
});

从本质上讲,这是控制反转的一种形式:在指定的点上,通用代码段调用外部提供的专用代码段的实践。

通常,这是通过使用(通常是抽象的)类或接口——并通过它们进行虚拟调用来实现的。委托和lambdas只是允许您更简洁地表达相同的东西,而编译器则在幕后完成无聊的工作(如声明新类,捕获所需的变量)。

在实现IDisposable的NetOutgoingMessage类周围创建一个包装器。

public class AutoMessage : IDisposable
{
    private const NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced;
    public NetPeer Peer { get; private set; }
    public List<NetConnection> Recipients { get; private set; } 
    public NetOutgoingMessage Message { get; private set; }
    public AutoMessage(NetPeer peer, List<NetConnection> recipients)
    {
        Peer = peer;
        Recipients = recipients;
        Message = peer.CreateMessage();
    }
    public void Dispose()
    {
        Peer.SendMessage(Message, Recipients, method, 0);
    }
}

你可以通过using:

使用它
var data = 123;
using (var msg = new AutoMessage(Client, Client.Connections))
{
    msg.Message.Write(data);
}

另一个选择是创建一个接口IMessage,它有EncodeDecode的方法定义,并允许其他类实现它们。然后创建一个Send方法,它将写入消息类型并运行Encode方法。

最新更新