1

抱歉,但想不出更好的方式来在标题中描述这一点。我也不是真正的开发人员,所以如果我混淆了我的字段、变量、对象和方法,请原谅。

无论如何,我有一些 C# 代码为我的类声明了一个私有变量,它在整个类中都可用。然而,在代码中,我实际上决定了它被声明为什么。当我跳入另一种方法时,由于原始声明,对象/变量的某些功能不可用。

private NetPeer _peer; //initially declared here so it's visible in the entire class
....
public void Initialise()
{
  if("some arbitrary validation") 
  {
    _peer = new NetServer(_config); // This is now a NetServer object and not NetPeer, but works fine
  }
  else
  {
    _peer = new NetClient(_config); // This is now a NetClient object and not NetPeer, but works fine
  }
  _peer.Start(); // This works fine as NetClient or NetServer. The method is available to both
}

public void SendIt()
{
  _peer.SendToAll(_message); //Now this "SendToAll" is only available with the NetServer and not NetClient. At runtime this fails miserably as you would expect
}

那么有没有办法声明私有“_peer”变量而不将其定义为 NetServer 或 NetClient 直到稍后,或者我需要重新访问我的其余代码并使用两个单独的变量运行。

它与问题并没有明显相关,但我使用的是 Lidgren 库,它是 NetServer 和 NetClient 的来源。我想它很容易是这里引用的任何其他类或方法。

我还删除了许多其他逻辑和代码来展示这个例子。

**编辑:所以我没有意识到问一个通用的问题会引发这样的战斗。代码现在运行良好,我使用了 Damien 的建议,因为这对我来说是最容易理解的: ((NetServer)_peer).SendToAll(_message);

感谢所有为我的问题提供积极帮助的人...

4

5 回答 5

0

您可以使用接口并让 NetServer 或 NetClient 从它派生

于 2013-04-18T13:55:51.637 回答
0

您可以编写如下内容:

public void SendIt()
{
  var server = _peer as NetServer;
  if(_peer == null) throw new InvalidOperationException("SendIt called when we're not the server");
  server.SendToAll(_message);
}

同样在其他仅适用于一种类型或另一种类型的方法中。我本可以省略这if(_peer ...条线,但那会留下NullReferenceException- 我更喜欢切换到更有意义的异常类型,同时能够提供关于具体哪里出错的提示。

同样,我本可以进行直接演员((NetServer)_peer).SendToAll(...,但这会引发一个InvalidCastException需要更多挖掘才能诊断问题的结果。我更喜欢使用as并尝试提供尽可能丰富的诊断体验。

于 2013-04-18T14:03:28.297 回答
0

您可以添加两个包装器属性以在您的类中使用:

private NetServer _peerServer
{
  get { return _peer as NetServer; }
}
private NetClient _peerClient
{
  get { return _peer as NetClient; }
}

任何时候使用这两个属性时,都需要进行空检查。例如:

public void SendIt()
{
  if(_peerServer == null) throw new InvalidOperationException("_peer is not a NetServer");
  _peerServer.SendToAll(_message); 
}

不过,这并不是非常优雅。你真正应该做的是一些重构。将类拆分为单独的服务器/客户端相关部分,可能具有基类中的通用功能,将是最干净的选择。

于 2013-04-18T14:06:56.563 回答
0

这取决于您是否希望您的客户在您点击时也发送消息SendIt()

如果这样做,您可以执行以下操作:

public void SendIt()
{
  if (_peer is NetServer)
    (_peer as NetServer).SendToAll(_message);
  else
    (_peer as NetClient).SendMessage(_message); //as radarbob says it is defined in the Lidgren library, I wouldn't know
}

如果你不这样做,你可以这样做(或遵循 Damien 的建议):

public void SendIt()
{
  if (!(_peer is NetServer)) throw new InvalidOperationException("SendIt called when we're not the server");
  (_peer as NetServer).SendToAll(_message);
}
于 2013-04-18T14:35:07.483 回答
-2

NetServer并且NetClient都继承自NetPeer. SendToAll()中未定义NetPeer,因此您必须使用SendMessage()中定义的方法NetPeer。这适用于任何继承类。

编辑 问题说它使用了一种叫做Lidgren library. 这始终是寻找答案的第一个地方。

于 2013-04-18T14:13:25.050 回答