银河

SKYIV STUDIO

  博客园 :: 首页 :: 博问 :: 闪存 :: :: :: 订阅 订阅 :: 管理 ::
  268 随笔 :: 2 文章 :: 2616 评论 :: 140万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

上图中有大量的类、结构、枚举和委托,其中绝大部分都是 internal 或者 private 的,也就是说只能在本程序集内部使用,对外是不可见的。

我们先从简单的,为别的类型所使用的类型开始阅读源代码吧。

Locale 类 (internal sealed class)

现在来看看 mcs/build/common/Locale.cs:

01:  //
02:  // Locale.cs
03:  //
04:  // Author:
05:  //   Miguel de Icaza (miguel@ximian.com)
06:  //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
07:  //
08:  // (C) 2001 - 2003 Ximian, Inc (http://www.ximian.com)
09:  //
10:  
11:  //
12:  // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13:  //
14:  // Permission is hereby granted, free of charge, to any person obtaining
15:  // a copy of this software and associated documentation files (the
16:  // "Software"), to deal in the Software without restriction, including
17:  // without limitation the rights to use, copy, modify, merge, publish,
18:  // distribute, sublicense, and/or sell copies of the Software, and to
19:  // permit persons to whom the Software is furnished to do so, subject to
20:  // the following conditions:
21:  // 
22:  // The above copyright notice and this permission notice shall be
23:  // included in all copies or substantial portions of the Software.
24:  // 
25:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32:  //
33:  
34:  using System;
35:  
36:  internal sealed class Locale {
37:  
38:      private Locale ()
39:      {
40:      }
41:  
42:      public static string GetText (string msg)
43:      {
44:          return msg;
45:      }
46:  
47:      public static string GetText (string fmt, params object [] args)
48:      {
49:          return String.Format (fmt, args);
50:      }
51:  }

这个 Locale 类被修饰为 internal,只能在本程序集内部使用。它也是一个密封类,并且构造函数只有一个私有的,因此它即不能被继承,也无法创建该类的实例。它目前仅有的两个方法都是静态的。我不明白为什么 Miguel de Icaza 和 Andreas Nahr 不干脆把它声明为静态类。此外,这个类位于全局命名空间中,这也不是好的做法。

从这个类的名称 Locale 和它现有的两个静态方法 GetText 来看,它是用来提供本地化的功能的。目前并没有实现任何本地化的功能,仅仅是简单地将输入的字符串原样返回而已。

在 Console.dll 这个项目中,Locale 类仅在 Buffer.cs 中使用过七次。

MonoTODOAttributes 类及其派生类 (internal class)

下面是 mcs/build/common/MonoTODOAttribute.cs:

001:  //
002:  // MonoTODOAttribute.cs
003:  //
004:  // Authors:
005:  //   Ravi Pratap (ravi@ximian.com)
006:  //   Eyal Alaluf <eyala@mainsoft.com> 
007:  //
008:  // (C) Ximian, Inc.  http://www.ximian.com
009:  //
010:  
011:  //
012:  // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
013:  // Copyright (C) 2006 Mainsoft, Inc (http://www.mainsoft.com)
014:  //
015:  // Permission is hereby granted, free of charge, to any person obtaining
016:  // a copy of this software and associated documentation files (the
017:  // "Software"), to deal in the Software without restriction, including
018:  // without limitation the rights to use, copy, modify, merge, publish,
019:  // distribute, sublicense, and/or sell copies of the Software, and to
020:  // permit persons to whom the Software is furnished to do so, subject to
021:  // the following conditions:
022:  // 
023:  // The above copyright notice and this permission notice shall be
024:  // included in all copies or substantial portions of the Software.
025:  // 
026:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
027:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
028:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
029:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
030:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
031:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
032:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
033:  //
034:  
035:  namespace System {
036:      
037:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
038:      internal class MonoTODOAttribute : Attribute {
039:  
040:          string comment;
041:          
042:          public MonoTODOAttribute ()
043:          {
044:          }
045:  
046:          public MonoTODOAttribute (string comment)
047:          {
048:              this.comment = comment;
049:          }
050:  
051:          public string Comment {
052:              get { return comment; }
053:          }
054:      }
055:  
056:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
057:      internal class MonoDocumentationNoteAttribute : MonoTODOAttribute {
058:  
059:          public MonoDocumentationNoteAttribute (string comment)
060:              : base (comment)
061:          {
062:          }
063:      }
064:  
065:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
066:      internal class MonoExtensionAttribute : MonoTODOAttribute {
067:  
068:          public MonoExtensionAttribute (string comment)
069:              : base (comment)
070:          {
071:          }
072:      }
073:  
074:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
075:      internal class MonoInternalNoteAttribute : MonoTODOAttribute {
076:  
077:          public MonoInternalNoteAttribute (string comment)
078:              : base (comment)
079:          {
080:          }
081:      }
082:  
083:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
084:      internal class MonoLimitationAttribute : MonoTODOAttribute {
085:  
086:          public MonoLimitationAttribute (string comment)
087:              : base (comment)
088:          {
089:          }
090:      }
091:  
092:      [AttributeUsage (AttributeTargets.All, AllowMultiple=true)]
093:      internal class MonoNotSupportedAttribute : MonoTODOAttribute {
094:  
095:          public MonoNotSupportedAttribute (string comment)
096:              : base (comment)
097:          {
098:          }
099:      }
100:  }

上述 C# 源程序中共定义了 System 命名空间中的六个 internal 类:

  1. MonoTODOAttribute: internal class,派生自 Attribute 类,是以下五个类的基类。 
  2. MonoDocumentationNoteAttribute: internal class
  3. MonoExtensionAttribute: internal class
  4. MonoInternalNoteAttribute: internal class
  5. MonoLimitationAttribute: internal class
  6. MonoNotSupportedAttribute: internal class

这六个类都是直接或间接地从 Attribute 类派生,因此它们都是特性,目的是将预定义的系统信息或用户定义的自定义信息与目标元素相关联。目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性、返回值、结构或其他特性。AttributeTargets.All 指明它们可以作用于所有上述目标元素。AllowMultiple=true 指明它们每一个都可以在同一目标元素上多次使用(可以携带不同的以字符串表示的信息)。MonoTODOAttribute 类有两个构造函数,分别是无参数的构造函数和需要一个字符串参数的构造函数。而其余五个类非常相似,都只有需要一个字符串参数的构造函数。

在 Console.dll 这个项目中,MonoTODO 特性在 TermInfoDriver.cs 中被使用过一次,MonoLimitation 特性在 Console.cs 中被使用过十一次。其他四个特性没有在这个项目中使用。

另外,把这六个类分别放在六个不同的 .cs 文件中会不会更好一点?

ControlCharacters 类 (internal class)

下面就是 mcs/class/corlib/System/ControlCharacters.cs:

01:  //
02:  // System.TermInfoBooleans
03:  //
04:  // Authors:
05:  //    Gonzalo Paniagua Javier (gonzalo@ximian.com)
06:  //
07:  // (C) 2009 Novell, Inc (http://www.novell.com)
08:  //
09:  
10:  //
11:  // Permission is hereby granted, free of charge, to any person obtaining
12:  // a copy of this software and associated documentation files (the
13:  // "Software"), to deal in the Software without restriction, including
14:  // without limitation the rights to use, copy, modify, merge, publish,
15:  // distribute, sublicense, and/or sell copies of the Software, and to
16:  // permit persons to whom the Software is furnished to do so, subject to
17:  // the following conditions:
18:  // 
19:  // The above copyright notice and this permission notice shall be
20:  // included in all copies or substantial portions of the Software.
21:  // 
22:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29:  //
30:  // These values are taken from 'man 5 terminfo' and /usr/include/term.h.
31:  // They are the indexes for the boolean capabilities in a terminfo file.
32:  namespace System {
33:      class ControlCharacters {
34:          public const int Intr = 0;
35:          public const int Quit = 1;
36:          public const int Erase = 2;
37:          public const int Kill = 3;
38:          public const int EOF = 4;
39:          public const int Time = 5;
40:          public const int Min = 6;
41:          public const int SWTC = 7;
42:          public const int Start = 8;
43:          public const int Stop = 9;
44:          public const int Susp = 10;
45:          public const int EOL = 11;
46:          public const int Reprint = 12;
47:          public const int Discard = 13;
48:          public const int WErase = 14;
49:          public const int LNext = 15;
50:          public const int EOL2 = 16;
51:      }
52:  }

上述源程序的第 33 行虽然没有 internal 修饰符,但是根据 C# 语法,class 的默认修饰符就是 internal。另外,第 2 行的注释是“System.TermInfoBooleans”,这不正确,应该改为“System.ControlCharacters”。还有,如果在第 33 行加上 static 关键字,将该类声明为静态类更好一些。或者改为结构(struct)?这里不使用枚举(enum),是因为它们是要作为数组的下标使用。如果是枚举的话,在使用时还需要转换为 int 类型。

在 Console.dll 这个项目中,ControlCharacters 类只在 TermInfoDriver.cs 中被使用过两次。

ConsoleKeyInfo 结构 (public struct)

下面就是 mcs/class/corlib/System/ConsoleKeyInfo.cs:

001:  //
002:  // System.ConsoleKeyInfo.cs
003:  //
004:  // Authors:
005:  //    Gonzalo Paniagua Javier (gonzalo@ximian.com)
006:  //
007:  // (C) 2005 Novell, Inc (http://www.novell.com)
008:  //
009:  
010:  //
011:  // Permission is hereby granted, free of charge, to any person obtaining
012:  // a copy of this software and associated documentation files (the
013:  // "Software"), to deal in the Software without restriction, including
014:  // without limitation the rights to use, copy, modify, merge, publish,
015:  // distribute, sublicense, and/or sell copies of the Software, and to
016:  // permit persons to whom the Software is furnished to do so, subject to
017:  // the following conditions:
018:  // 
019:  // The above copyright notice and this permission notice shall be
020:  // included in all copies or substantial portions of the Software.
021:  // 
022:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
023:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
024:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
025:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
026:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
027:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
028:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
029:  //
030:  namespace System {
031:      [Serializable]
032:      public struct ConsoleKeyInfo {
033:          internal static ConsoleKeyInfo Empty = new ConsoleKeyInfo ('\0', 0, false, false, false);
034:          ConsoleKey key;
035:          char keychar;
036:          ConsoleModifiers modifiers;
037:  
038:          public ConsoleKeyInfo (char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
039:          {
040:              this.key = key;
041:              this.keychar = keyChar;
042:              modifiers = 0;
043:              SetModifiers (shift, alt, control);
044:          }
045:  
046:          internal ConsoleKeyInfo (ConsoleKeyInfo other)
047:          {
048:              this.key = other.key;
049:              this.keychar = other.keychar;
050:              this.modifiers = other.modifiers;
051:          }
052:  
053:          internal void SetKey (ConsoleKey key)
054:          {
055:              this.key = key;
056:          }
057:  
058:          internal void SetKeyChar (char keyChar)
059:          {
060:              this.keychar = keyChar;
061:          }
062:  
063:          internal void SetModifiers (bool shift, bool alt, bool control)
064:          {
065:              this.modifiers = (shift) ? ConsoleModifiers.Shift : 0;
066:              this.modifiers |= (alt) ? ConsoleModifiers.Alt : 0;
067:              this.modifiers |= (control) ? ConsoleModifiers.Control : 0;
068:          }
069:  
070:          public ConsoleKey Key {
071:              get { return key; }
072:          }
073:  
074:          public char KeyChar {
075:              get { return keychar; }
076:          }
077:  
078:          public ConsoleModifiers Modifiers {
079:              get { return modifiers; }
080:          }
081:          
082:          public override bool Equals (object value)
083:          {
084:              if (!(value is ConsoleKeyInfo))
085:                  return false;
086:              return Equals ((ConsoleKeyInfo) value);
087:          }
088:          
089:          public static bool operator == (ConsoleKeyInfo a, ConsoleKeyInfo b)
090:          {
091:              return a.Equals (b);
092:          }
093:          
094:          public static bool operator != (ConsoleKeyInfo a, ConsoleKeyInfo b)
095:          {
096:              return !a.Equals (b);
097:          }
098:          
099:          public bool Equals (ConsoleKeyInfo obj)
100:          {
101:              return key == obj.key && obj.keychar == keychar && obj.modifiers == modifiers;
102:          }
103:          
104:          public override int GetHashCode ()
105:          {
106:              return key.GetHashCode () ^ keychar.GetHashCode () ^ modifiers.GetHashCode ();
107:          }
108:      }
109:  }

上述源程序定义了 ConsoleKeyInfo 结构,用于描述按下的控制台键,包括控制台键表示的字符以及 Shift、Alt 和 Ctrl 修改键的状态。它不应由用户创建,而是作为 Console.ReadKey 方法的响应返回给用户。

ConsoleKeyInfo 结构定义了以下实例字段:

  1. key: 类型为 ConsoleKey,用于描述按下的控制台键。(第 34 行)
  2. keychar: 类型为 char,指出控制台键表示的字符。(第 35 行)
  3. modifiers: 类型为 ConsoleModifiers,指示 Shift、Alt 和 Ctrl 修改键的状态。(第 36 行)

第 33 行定义了一个 internal 静态属性 Empty,用作 NullConsoleDriver 类的 ReadKey 方法的返回值。

第 46 行到第 51 行定义了一个 internal 的复制构造函数,用于 CStreamWriter 类的 WriteKey 方法中。

第 38 行到第 44 行定义了一个 public 的构造函数,用于 TermInfoDriver 和 WindowsConsoleDriver 类中。在该构造函数中,使用传入的参数给上述三个字段赋值。其实第 42 行的“modifiers = 0;”语句是多余的,因为接下来的第 43 行中调用的 SetModifiers 方法会正确地给 modifiers 字段赋值,用不着先把该字段清零。

第 46 行到第 68 行的三个 internal 的 SetXXX 方法分别给上述三个字段赋值。

第 70 行到第 80 行的三个 public 的属性分别获取上述三个字段的值。

第 89 行到第 97 行的两个方法重载了等于(==)和不等于(!=)运算符,仅是调用下述的 Equals 方法。

第 99 行到第 102 行的 Equals 方法现了强类型的相等性。

第 82 行到第 87 行的 Equals 方法重写了基类的 Equals 方法,在第 86 行调用了前述 Equals 方法。

第 104 行到第 107 行的 GetHashCode 方法重写了基类的 GetHashCode 方法,返回哈希码。

ConsoleKeyInfo 结构在 Console.dll 项目中广泛使用,Console.cs、ConsoleDriver.cs、CStreamReader.cs、CStreamWriter.cs、IConsoleDriver.cs、NullConsoleDriver.cs、TermInfoDriver.cs 和 WindowsConsoleDriver.cs 中都有使用 ConsoleKeyInfo 结构。

因为 NullConsoleDriver.cs 中使用了 ConsoleKeyInfo 结构的 internal 静态属性 Empty,CStreamWriter.cs 中使用了 ConsoleKeyInfo 结构的 internal 复制构造函数,所以在我们的 Cosnole.dll 项目中需要包含 ConsoleKeyInfo.cs。不然的话,作为 public 的结构,我们可以直接使用 mscorlib.dll 中的 ConsoleKeyInfo 结构。

 

(未完待续)

posted on   银河  阅读(2410)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示