本文是我博客的镜像,原文地址是:

http://www.greatony.com/?p=73 

系列文章引言

众所周知,我是个彻彻底底的C#控,但是没有东西是完美的,C#也是一样,所以在这里我就yy一下,设想一下我心中C#将来的样子,故取名为《C#狂想曲》系列。

测试程序

为了体现对C#的变化,我设定了一份游戏编程中经常遇到的程序作为标准来体现变化。

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class Player
 7     {
 8         public int Id { getset; }
 9         public int UserId { getset; }
10         public string Name { getset; }
11     }
12 
13     public interface IPlayerService
14     {
15         int CreatePlayer(int userId, string name);
16         Player GetPlayer(int playerId);
17         Player GetPlayer(string name);
18         Player GetUserPlayer(int userId);
19     }
20 
21     public class PlayerService : IPlayerService
22     {
23         public int CreatePlayer(int userId, string name)
24         {
25             var player = new Player
26             {
27                 Id = _playerIndex++,
28                 UserId = userId,
29                 Name = name;
30             };
31 
32             _players.Add(player);
33 
34             return player.Id;
35         }
36 
37         public Player GetPlayer(int playerId)
38         {
39             return _players.FirstOrDefault(p => p.Id == playerId);
40         }
41 
42         public Player GetPlayer(string playerName)
43         {
44             return _players.FirstOrDefault(p => p.Name == playerName);
45         }
46 
47         public Player GetUserPlayer(int userId)
48         {
49             return _players.FirstOrDefault(p => p.UserId == userId);
50         }
51 
52         private int _playerIndex = 0;
53         private List<Player> _players = new List<Player>();
54     }
55 }

 

很简单的程序,然后显然这是一个线程不安全的程序,线程安全的版本,我们回头再说。

去类型化

C#是一个强类型语言,相对来说也是一个静态语言。然而现在的程序越来越灵活,C#的静态性已经开始逐步制约了创造力的发挥。在处理Web场景和游戏场景中已经变的越来越力不从心,所以,在这里提出一个去类型化的想法:

类似JavaScript,申明变量、声明函数时,不需要声明类型。则上述程序变成

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class Player
 7     {
 8         public var Id { getset; }
 9         public var UserId { getset; }
10         public var Name { getset; }
11     }
12 
13     public interface IPlayerService
14     {
15         function CreatePlayer(userId, name);
16         function GetPlayer(playerId);
17         function GetPlayer(name);
18         function GetUserPlayer(userId);
19     }
20 
21     public class PlayerService : IPlayerService
22     {
23         public function CreatePlayer(userId, name)
24         {
25             var player = new Player
26             {
27                 Id = _playerIndex++,
28                 UserId = userId,
29                 Name = name;
30             };
31 
32             _players.Add(player);
33 
34             return player.Id;
35         }
36 
37         public function GetPlayer(playerId)
38         {
39             return _players.FirstOrDefault(p => p.Id == playerId);
40         }
41 
42         public function GetPlayer(playerName)
43         {
44             return _players.FirstOrDefault(p => p.Name == playerName);
45         }
46 
47         public function GetUserPlayer(userId)
48         {
49             return _players.FirstOrDefault(p => p.UserId == userId);
50         }
51 
52         private var _playerIndex = 0;
53         private var _players = new List<Player>();
54     }
55 }

 

然而这会带来一个问题,就是两个GetPlayer的签名重复了,所以我们暂时取消C#的重载功能,变成这样:

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class Player
 7     {
 8         public var Id { getset; }
 9         public var UserId { getset; }
10         public var Name { getset; }
11     }
12 
13     public interface IPlayerService
14     {
15         function CreatePlayer(userId, name);
16         function GetPlayer(playerId);
17         function GetPlayerByName(name);
18         function GetUserPlayer(userId);
19     }
20 
21     public class PlayerService : IPlayerService
22     {
23         public function CreatePlayer(userId, name)
24         {
25             var player = new Player
26             {
27                 Id = _playerIndex++,
28                 UserId = userId,
29                 Name = name;
30             };
31 
32             _players.Add(player);
33 
34             return player.Id;
35         }
36 
37         public function GetPlayer(playerId)
38         {
39             return _players.FirstOrDefault(p => p.Id == playerId);
40         }
41 
42         public function GetPlayerByName(playerName)
43         {
44             return _players.FirstOrDefault(p => p.Name == playerName);
45         }
46 
47         public function GetUserPlayer(userId)
48         {
49             return _players.FirstOrDefault(p => p.UserId == userId);
50         }
51 
52         private var _playerIndex = 0;
53         private var _players = new List<Player>();
54     }
55 }

 

既然类型都不重要了,那么泛型也没有存在的必要了,去除泛型,变成这样:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class Player
 7     {
 8         public var Id { getset; }
 9         public var UserId { getset; }
10         public var Name { getset; }
11     }
12 
13     public interface IPlayerService
14     {
15         function CreatePlayer(userId, name);
16         function GetPlayer(playerId);
17         function GetPlayerByName(name);
18         function GetUserPlayer(userId);
19     }
20 
21     public class PlayerService : IPlayerService
22     {
23         public function CreatePlayer(userId, name)
24         {
25             var player = new Player
26             {
27                 Id = _playerIndex++,
28                 UserId = userId,
29                 Name = name;
30             };
31 
32             _players.Add(player);
33 
34             return player.Id;
35         }
36 
37         public function GetPlayer(playerId)
38         {
39             return _players.FirstOrDefault(p => p.Id == playerId);
40         }
41 
42         public function GetPlayerByName(playerName)
43         {
44             return _players.FirstOrDefault(p => p.Name == playerName);
45         }
46 
47         public function GetUserPlayer(userId)
48         {
49             return _players.FirstOrDefault(p => p.UserId == userId);
50         }
51 
52         private var _playerIndex = 0;
53         private var _players = new List();
54     }
55 }

 

如果类型不重要了,那么什么重要呢?当然是通讯的接口重要。

所以我们没有必要继续显式的声明接口以及entity类了,把程序编程这样:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class PlayerService
 7     {
 8         public function CreatePlayer(userId, name)
 9         {
10             var player = {
11                 Id = _playerIndex++,
12                 UserId = userId,
13                 Name = name
14             };
15 
16             _players.Add(player);
17 
18             return player.Id;
19         }
20 
21         public function GetPlayer(playerId)
22         {
23             return _players.FirstOrDefault(p => p.Id == playerId);
24         }
25 
26         public function GetPlayerByName(playerName)
27         {
28             return _players.FirstOrDefault(p => p.Name == playerName);
29         }
30 
31         public function GetUserPlayer(userId)
32         {
33             return _players.FirstOrDefault(p => p.UserId == userId);
34         }
35 
36         private var _playerIndex = 0;
37         private var _players = new List();
38     }
39 }

 

既然取消了明确的entity声明,那么就把创建entity对象的形式变成和javascript兼容的形式把:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class PlayerService
 7     {
 8         public function CreatePlayer(userId, name)
 9         {
10             var player = {
11                 Id: _playerIndex++,
12                 UserId: userId,
13                 Name: name
14             };
15 
16             _players.Add(player);
17 
18             return player.Id;
19         }
20 
21         public function GetPlayer(playerId)
22         {
23             return _players.FirstOrDefault(p => p.Id == playerId);
24         }
25 
26         public function GetPlayerByName(playerName)
27         {
28             return _players.FirstOrDefault(p => p.Name == playerName);
29         }
30 
31         public function GetUserPlayer(userId)
32         {
33             return _players.FirstOrDefault(p => p.UserId == userId);
34         }
35 
36         private var _playerIndex = 0;
37         private var _players = new List();
38     }
39 }

 

至此,C#已经不具有编译时强类型了。继续我们的改造~~~

弱化语法

C#从C/C++中继承了很多格式化的,教条的语法,就算我们改成了javascript的形式,我们仍然需要使用var和function来显式的区分函数和变量。

在javascript中,这个限制来源于function作为第一类对象,可以在任何地方声明,如果不限制的话,会导致程序混淆。

然而在c#里面,函数作为类的成员存在,所以没有这个问题,自然的,也不需要使用function和var关键字来区分类的方法和类的数据成员,那么可以变成这样:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class PlayerService
 7     {
 8         public CreatePlayer(userId, name)
 9         {
10             var player = {
11                 Id: _playerIndex++,
12                 UserId: userId,
13                 Name: name
14             };
15 
16             _players.Add(player);
17 
18             return player.Id;
19         }
20 
21         public GetPlayer(playerId)
22         {
23             return _players.FirstOrDefault(p => p.Id == playerId);
24         }
25 
26         public GetPlayerByName(playerName)
27         {
28             return _players.FirstOrDefault(p => p.Name == playerName);
29         }
30 
31         public GetUserPlayer(userId)
32         {
33             return _players.FirstOrDefault(p => p.UserId == userId);
34         }
35 
36         private _playerIndex = 0;
37         private _players = new List();
38     }
39 }

 

在使用new关键字调用无参的构造函数的时候,那一对()是多余的,所以我们可以去掉他们:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5 {
 6     public class PlayerService
 7     {
 8         public CreatePlayer(userId, name)
 9         {
10             var player = {
11                 Id: _playerIndex++,
12                 UserId: userId,
13                 Name: name
14             };
15 
16             _players.Add(player);
17 
18             return player.Id;
19         }
20 
21         public GetPlayer(playerId)
22         {
23             return _players.FirstOrDefault(p => p.Id == playerId);
24         }
25 
26         public GetPlayerByName(playerName)
27         {
28             return _players.FirstOrDefault(p => p.Name == playerName);
29         }
30 
31         public GetUserPlayer(userId)
32         {
33             return _players.FirstOrDefault(p => p.UserId == userId);
34         }
35 
36         private _playerIndex = 0;
37         private _players = new List;
38     }
39 }

 

我想,在一个文件里面,层层相套的花括号已经太让人心烦了,所以,我们可以去掉不必要的花括号,包括namespace、class和function的,如果他们都只包含一个他们的子元素,那么可以不写花括号:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public CreatePlayer(userId, name)
 8         {
 9             var player = {
10                 Id: _playerIndex++,
11                 UserId: userId,
12                 Name: name
13             };
14 
15             _players.Add(player);
16 
17             return player.Id;
18         }
19 
20         public GetPlayer(playerId)
21             return _players.FirstOrDefault(p => p.Id == playerId);
22 
23         public GetPlayerByName(playerName)
24             return _players.FirstOrDefault(p => p.Name == playerName);
25 
26         public GetUserPlayer(userId)
27             return _players.FirstOrDefault(p => p.UserId == userId);
28 
29         private _playerIndex = 0;
30         private _players = new List;
31     }

 

既然lambda的语法如此的简介优美,那么我们为什么不使用lambda的语法来写method呢?

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public CreatePlayer(userId, name) =>
 8         {
 9             var player = {
10                 Id: _playerIndex++,
11                 UserId: userId,
12                 Name: name
13             };
14 
15             _players.Add(player);
16 
17             return player.Id;
18         }
19 
20         public GetPlayer(playerId) => _players.FirstOrDefault(p => p.Id == playerId);
21         public GetPlayerByName(playerName) => _players.FirstOrDefault(p => p.Name == playerName);
22         public GetUserPlayer(userId) => _players.FirstOrDefault(p => p.UserId == userId);
23 
24         private _playerIndex = 0;
25         private _players = new List;
26     }

 

哦,天哪,原来c#还可以这么简洁

加上Pattern Match

现在没有了重载,真是举步维艰啊,写程序真是太麻烦了。但是,别着急,之所以取消了重载这个非常好用的功能,是因为我们要加上一个比重载还要好用的功能:模式匹配:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public CreatePlayer(userId, name)
 8         {
 9             var player = {
10                 Id: _playerIndex++,
11                 UserId: userId,
12                 Name: name
13             };
14 
15             _players.Add(player);
16 
17             return player.Id;
18         }
19 
20         public GetPlayer("playerId", playerId) => _players.FirstOrDefault(p => p.Id == playerId);
21         public GetPlayer("playerName", playerName) => _players.FirstOrDefault(p => p.Name == playerName);
22         public GetPlayer("userId", userId) => _players.FirstOrDefault(p => p.UserId == userId);
23 
24         private _playerIndex = 0;
25         private _players = new List;
26     }

 

哇,这样的c#好美啊。

使用C++式的访问控制描述符形式

C#的方式确实挺好的,但是,这样容易让人把public的和private的东西交错放置,这就太乱了,所以使用C++形式的访问控制描述符吧:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public:
 8             CreatePlayer(userId, name)
 9             {
10                 var player = {
11                     Id: _playerIndex++,
12                     UserId: userId,
13                     Name: name
14                 };
15 
16                 _players.Add(player);
17 
18                 return player.Id;
19             }
20 
21             GetPlayer("playerId", playerId) => _players.FirstOrDefault(p => p.Id == playerId);
22             GetPlayer("playerName", playerName) => _players.FirstOrDefault(p => p.Name == playerName);
23             GetPlayer("userId", userId) => _players.FirstOrDefault(p => p.UserId == userId);
24 
25         private:
26             _playerIndex = 0;
27             _players = new List;
28     }

哇,这真的好清晰,好美啊

加上动态属性吧

神马?那indexer情何以堪?好吧,那就先忘记indexer吧,把我们亲爱的动态属性先弄到再说:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public:
 8             CreatePlayer(userId, name)
 9             {
10                 var player = {
11                     Id: _playerIndex++,
12                     UserId: userId,
13                     Name: name
14                 };
15 
16                 _players.Add(player);
17 
18                 return player.Id;
19             }
20 
21             GetPlayer(field, playerId) => _players.FirstOrDefault(p => p[field] == playerId);
22 
23         private:
24             _playerIndex = 0;
25             _players = new List;
26     }

 

加上Guard吧

万一有人不怀好意,使用其他ws的参数来攻击怎么办?加上Guard吧:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public:
 8             CreatePlayer(userId, name)
 9             {
10                 var player = {
11                     Id: _playerIndex++,
12                     UserId: userId,
13                     Name: name
14                 };
15 
16                 _players.Add(player);
17 
18                 return player.Id;
19             }
20 
21             GetPlayer(field, playerId)
22                 when (field == "Id" || field == "UserId" || field == "Name")
23                 => _players.FirstOrDefault(p => p[field] == playerId);
24 
25         private:
26             _playerIndex = 0;
27             _players = new List;
28     }

 

加上in关键字吧

哦,天哪,这太丑陋了,就不能弄个好看点的东西?

唔~~~那就加上in关键字吧:

 1 using System;
 2 using System.Collections;
 3 
 4 namespace Orandea.Webgame
 5     public class PlayerService
 6     {
 7         public:
 8             CreatePlayer(userId, name)
 9             {
10                 var player = {
11                     Id: _playerIndex++,
12                     UserId: userId,
13                     Name: name
14                 };
15 
16                 _players.Add(player);
17 
18                 return player.Id;
19             }
20 
21             GetPlayer(field, playerId)
22                 when (field in ["Id""UserId""Name"])
23                 => _players.FirstOrDefault(p => p[field] == playerId);
24 
25         private:
26             _playerIndex = 0;
27             _players = new List;
28     }

 

 

恩,今天就先到这里吧,到下一节,我们加上一些消息通讯的东西,瓦咔咔 

 

posted on 2010-11-02 15:08  TonyHuang  阅读(1833)  评论(26编辑  收藏  举报