将变量声明为一种类型,然后使用"new"到另一种类型

本文关键字:quot 类型 声明 变量 new 另一种 然后 一种 | 更新日期: 2023-09-27 18:09:57

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

无论如何,我有一些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);

感谢所有对我的问题给予积极帮助的人

将变量声明为一种类型,然后使用"new"到另一种类型

你可以这样写:

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,并尝试提供尽可能丰富的诊断体验。

您可以使用一个接口,并从它派生NetServer或NetClient

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

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); 
}

这并不是非常优雅。你真正应该做的是一点重构。将类拆分为独立的服务器/客户端依赖部分,也许在基类中使用公共功能,将是最干净的选择。

这取决于你是否想要你的客户端也发送消息当你点击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);
}

NetServerNetClient都继承自NetPeerSendToAll()没有在NetPeer中定义,因此必须使用NetPeer中定义的SendMessage()方法。这将适用于任何继承类。

编辑问题说它使用了一种叫做Lidgren library的东西。

相关文章: