论坛风格切换切换到宽版
  • 5287阅读
  • 4回复

[求助]C#中如何实现函数返回值的多态(封装的dll与满足条件的用户自定义类进行合作)? [复制链接]

上一主题 下一主题
离线argoran
 
发帖
33
樱饼
0
博丽神社的喝茶券(威望)
0
春度
7
交易币
0
只看楼主 倒序阅读 楼主  发表于: 2009-12-09
标题说的可能并不十分准确,还请大家看下面的问题描述。

我正在用C#做一个TCP连接的封装,在写网络消息收发这部分代码的时候遇到了一个问题:

接收网络消息的类先使用一个异步函数接收Byte数组形式的消息,然后把接收到的数组存放到一个队列(Queue<Byte[]>)里面。
接着,我写了这样一个Receive函数:
public CMessage Receive()
{
    if (queue.Count > 0)
        return new CMessage(queue.Dequeue())
    return null;
}

CMessage是一个已经定义好的用来表示网络消息的类,构造函数CMessage(Byte[] data)会分析作为参数的字节数组,把它转换成具体的消息内容。

现在的问题是,我希望能够让使用这个封装的用户自己来定义网络消息的结构,而不是只能使用我编写的CMessage类中规定的结构。
也就是说,我希望能够用一个接口或者抽象类之类的东西来代替这里的CMessage。但是由于接口和抽象类都不能实例化,所以Receive函数中的return语句就不能写成return new XXX(queue.Dequeue())。

我一直没有想到什么解决办法,所以想请教一下大家,像这种情况的话,有什么可行的方案吗?
P.S. 我也考虑过定义一个基类,然后在函数中返回这个基类的方案。但是由于不同的网络消息结构之间似乎并不具有太多的相似性,所以这个基类也不太好写。如果只是写一个空的基类的话,好像也不太合适。

====================

既然问题都写了这么长,干脆连demo也发一下吧。
《勇者GOGOGO》v091206 客户端7.58KB
《勇者GOGOGO》v091206 服务器端9.43KB

大致说来,这是个类似文字mud的网络游戏。但也不是完全一样的东西,我希望通过这个demo尝试的要素主要是以下几点:
1 玩家角色只有一次生命
2 玩家角色没有等级的区别
3 没有友方npc
4 玩家的行动会改变游戏中的世界
游戏的主要内容就是勇者斗怪兽:在一座被划分成许多矩形格子的小岛上,有一些格子被邪恶的怪兽占领了,并且这些怪兽会不断地去占领新的格子。玩家们作为勇者来到这座岛上,他们必须阻止怪兽占领整座岛屿,并最终打败岛上的所有怪兽。

目前的完成情况是实现了玩家注册登录的功能,实现了玩家在游戏世界中移动和聊天的功能。现在我在试着把demo中网络通信部分的代码封装起来,等封装完成后,就会开始逐步添加内容,完成游戏的系统。

下面是demo的使用说明:
客户端:
1 启动程序后,提示输入服务器地址。窗口中显示的默认服务器地址无效,客户端要问到开服务器的人的ip地址才能连接。
2 连接服务器后,出现连接正常的确认信息,并显示当前服务器上的总注册帐号数,以及当前在线帐号数。输入-create username password即可注册新用户,注意create前有一个减号,所有系统指令前都要加一个减号。
3 成功注册后,输入-login username password即可登录游戏。
4 登录游戏后,可以输入以下指令:
-charinfo
查看角色信息
-mapinfo
查看地图信息
-players
查看与自己位于同一格的玩家
-move direction
向四周移动 direction可以选择的有:east west north south
例如:-move east即向东移动
5 登录游戏后还可以进行聊天:
不输入减号,直接输入聊天内容,可以向所有位于同一格子内的玩家发送聊天消息例如:hi, how are you?这句话可以被所有和你在同一个格子的玩家看到
-username 聊天内容向指定玩家发送私聊消息例如:-Anover hi, where do you come from?如果Anover这个玩家存在并且在线的话,他就会收到这条hi, where do you come from?这条消息
6 输入-logout指令可以从游戏中登出,此时玩家不会再收到游戏中其他玩家的消息,但仍然与服务器保持连接。
7 输入-quit指令可以中断与服务器的连接,并退出游戏程序。

服务器:
1 启动程序后,提示输入服务器地址。这里要输入一个公网地址才可以,以10.0或者192.168开头的内网地址虽然程序显示初始化正常,但其他玩家是无法连接到这个服务器的。
2 当程序显示“开始监听8802端口……”表示服务器已经初始化完成,开始等待连接。当有客户端连接到服务器或与服务器断开连接时,服务器会出现提示。服务器窗口中还会显示所有客户端发送到服务器的消息。
3 输入-quit,可以退出服务器,所有玩家的信息将被保存到同一目录下的userInfo.txt文件中。所有连接服务器的客户端会收到“服务器关闭,连接断开”的消息。
4 输入-save,可以在不退出服务器的情况下,保存当前玩家信息到userInfo.txt文件中。
5 不输入减号,直接输入内容,可以以服务器的身份向所有连接到服务器的客户端发送消息。客户端会显示“server说:消息内容”。

需要注意的是,如果服务器不使用-quit指令,而是直接关闭窗口退出,并且又没有使用-save指令保存玩家信息的话,所有玩家此次游戏的信息都将丢失。客户端不需要一定使用-quit指令退出,直接关闭窗口即可。另外由于所有玩家的信息都是用txt格式不加密保存,大家不要使用自己平时惯用的帐户密码进行注册,否则大家的帐户密码有被服务器端窃取的可能。
[ 此帖被argoran在2009-12-09 17:08重新编辑 ]
厄啊啊啊啊啊!!
离线ryuka
发帖
234
樱饼
0
博丽神社的喝茶券(威望)
0
春度
37
交易币
0
只看该作者 1楼 发表于: 2009-12-21
这贴前些时间没看到.=v=
不知道符合不符合你的要求

void MessageQueue::Receive(IMessage m)
{
      if (queue.Count > 0)
        m.decodeMessage(queue.Dequeue());
}

void IMessage::decodeMessage(Byte[] b) = 0;// 或者你给个assert(false);

class MyMessage : public IMessage
{
    public void decodeMessage(Byte[] b)
    {
         // decode message
    }
}

MyMessage m = new MyMessage();
messageQueue.Recieve(m);
[ 此帖被ryuka在2009-12-21 23:11重新编辑 ]
。。。没啥签名。。。反正是一小号。。。
离线realanan
发帖
46
樱饼
0
博丽神社的喝茶券(威望)
0
春度
0
交易币
0
只看该作者 2楼 发表于: 2009-12-22
你可以用泛型进行返回,类似CMessage<T>
离线wdnm
发帖
232
樱饼
0
博丽神社的喝茶券(威望)
0
春度
23
交易币
0
只看该作者 3楼 发表于: 2014-03-24
用泛型+接口应该可以行。。。
东方好玩!
离线wdnm
发帖
232
樱饼
0
博丽神社的喝茶券(威望)
0
春度
23
交易币
0
只看该作者 4楼 发表于: 2014-03-24
额。。才发现我挖坟了。。不对啊。。这贴怎么冒到上面来了
东方好玩!
快速回复
限100 字节
 
上一个 下一个