我已经将My命名空间中所有默认的对象都介绍完了,相信大家已经开始体验到My的方便之处。但是对于一些高级用户来说,这些功能还显得有所欠缺。老手们有时也编写了类似My功能的类或函数,要是能把他们放到My命名空间中多好。My就像一个可随时访问的工具箱,除了里面已经有的工具以外,当然允许我们将自己的东西放进去。下面我们就来看看怎么扩展My命名空间。
添加自定义的类或模块
如果我们想要放进My中的函数都是静态的,那么直接把类或模块放入My命名空间是个方便的方法,做法非常简单,只要将类或模块定义在My命名空间中即可
Namespace My
Public Module Tools
Public Sub DoSomething()
'Some code here
End Sub
End Module
End Namespace
现在就可以直接用My.Tools来访问自定义的模块,很方便。
添加自定义类的实例
如果我们观察Visual Basic所提供的My命名空间成员,将发现他们都不是类本身,而是对象。因为所有的方法都做成静态毕竟不是最佳方法,我们有时候需要将一些自定义类的实例放到My命名空间中,这样不用的时候就比较节省内存,而且易于控制资源释放的问题。首先我们要定义自定义类,可以放在任何地方,而不必放到My命名空间中,这样就可以避免类名直接显示在My关键字后。然后,在My命名空间下,定义一个带有HideModuleNameAttribute的模块,名称可以随便起;最后在模块中设定访问自定义类实例的属性。假设我们的自定义类叫ToolsProxy,而自定义属性叫Tools,那么可以这样写:
'Namespace My
<HideModuleName()> _
Friend Module MyCustomModule
Private syncRoot As New Object
Private _tools As ToolsProxy
''' <summary>
''' Contains my custom tools.
''' </summary>
Public ReadOnly Property Tools() As ToolsProxy
Get
'Double check lock to ensure thread safty.
If _tools Is Nothing Then
SyncLock syncRoot
If _tools Is Nothing Then
_tools = New ToolsProxy
End If
End SyncLock
End If
Return _tools
End Get
End Property
End Module
有了HideModuleName这个Attribute,它本身就不会出现在My关键字后面,而它的属性则会显示。完成以后,你会发现My.Tools这次与Visual Basic内置在My中的对象没有任何区别了。此方法为扩展My最佳的方法,推荐使用。
扩展My.Application或My.Computer
有时候,我们不仅要将自定义的类添加到My中,还希望更进一步直接补充My.Application或My.Computer本身的功能。而这完全可以做到。Visual Basic提供了Partial关键字,他可以扩写当前项目中的类或结构,无论原先定义的时候是否加上了Partial关键字。于是我们就可以利用这一特征扩写定义看不见的My.Application或My.Computer。My.Application对应的是MyApplication类,而My.Computer对应的是MyComputer类。比如我们要给My.Computer增加一个新的功能——CdRomDriver属性,用以控制光驱的弹出、缩进与自动运行,就可以直接在My命名空间下扩写MyComputer类,如下:
'Namespace My
Partial Class MyComputer
Public ReadOnly Property CdRomDriver() As CdRomDriver
Get
'Codes here
End Get
End Property
End Class
这样就成功地给My.Computer添加了新的属性,你会发现My.Computer.CdRomDriver和其他My.Computer有完全一样的行为。同样,My.Application也可以通过Partial并添加自定义属性的方式进行扩展。
现在我们可以看出,My命名空间是完全开放和可编程的,我们可以自由发挥想象力,创造完全属于自己的My命名空间。
也许说到这里,C#的程序员已经很眼馋了,能不能在C#中使用My命名空间呢?答案是能,又不能。C#的设计者没有提供通过My来访问对象的方法,那么直接使用My是不可能了。但是Visual Basic的设计者已经考虑到了这些问题,将My命名空间中大多数功能开放了出来,让C#和其他语言的程序员可以用到他们。
在C#中使用My.Application
要使用My.Application,必须要继承System.Windows.Forms.WindowsFormsApplicationBase(该类位于Microsoft.VisualBasic.dll中)。继承之后我们要做几件事情,首先书写构造函数初始化MyApplication类,在Visual Basic中这些设置均为IDE生成,而C#则需要手工书写。然后重写OnCreateMainForm方法,这个方法设定了当前应用程序的主窗体。接下来书写My类,让他提供对MyApplication类的全局访问点。最后改写Main,在其中执行My.Application.Run()代替原来的Application.Run(),具体做法如下。
namespace WindowsApplication2.Properties
{
public class MyApplication : WindowsFormsApplicationBase
{
public MyApplication() : base(AuthenticationMode.Windows)
{
IsSingleInstance = false;
EnableVisualStyles = true;
ShutdownStyle = ShutdownMode.AfterMainFormCloses;
}
protected override void OnCreateMainForm()
{
//Sepecify the main form of your project
MainForm = new WindowsApplication2.Form1();
}
}
public static class My
{
private static MyApplication _Application;
private static object syncRoot = new object();
public static MyApplication Application
{
get {
if (_Application == null)
{
lock (syncRoot)
{
if (_Application == null)
{
_Application = new MyApplication();
}
} // end lock
} // end if
return _Application;
} // end get
}
}
}
修改Main函数:
[STAThread]
static void Main()
{
// Application.EnableVisualStyles();
// Application.EnableRTLMirroring();
// Application.Run(new Form1());
Properties.My.Application.Run();
}
这样我们就充分获得了My.Application的对象模型。但是有些动态生成的内容,如SplashScreen对象等,除非自己书写,否则无法使用。通过这种方法使用My.Application可以获得许多额外的好处,比如获得My.Application的事件支持,他们是跟应用程序运行状态密切相关的事件,非常有用。但是由于缺乏自动代码的支持,不能保证My.Application事件的全部行为都和Visual Basic一样。
在C#中使用My.Computer
要使用My.Computer我们无需像Application那样费劲了。Visual Basic的设计者将大部分供能放到了System的自命名空间中,可以很自然地使用他们:
My中的名称 | System中的名称 |
My.Computer.FileSystem | System.IO.FileSystem |
My.Application.AssemblyInfo | System.Reflection.AssemblyInfo* |
My.Computer.KeyBoard | System.Windows.Forms.KeyBoard |
My.Computer.Mouse | Sysetm.Widnows.Forms.Mouse |
注:System.Reflecton.AssemblyInfo只是My.Applicaton.AssemblyInfo的类型。
当然这不如Visual Basic中那样丰富,但是一般应用有FileSystem就足够了,其他功能用.NET Framework原本的方法也很简单。要注意,尽管这些类分散在System的各个字命名空间中,但是全部都位于Microsoft.VisualBasic.dll中,需要引用它才能使用。
在C#中使用My.Resources和My.Settings
一个好消息是,C#也内置了这两样功能,只要把My换成Properties就可以使用了,和Visual Basic一样方便。但是My.User、My.Forms和My.WebServices是真的没有了,要实现他们的功能,需要完全手工编码。