正在加载

82天的沉寂之后,新一篇日志

| 2008年9月13日星期六

6月23号之后我就没写过东西,一是先忙考试,考试结束回家两天半又奔赴沈阳,学了一个月日语之后终于回家了,然后20又回学校了。回学校以为会轻松点,不过紧接着就是泰克培训,太崩溃了。。。。

这两天终于有时间更新下我这个博客了。。。。

如果你喜欢本文,把它分享到 Twitter / 校内 / 鲜果 / Digg
或者把它收藏到 Delicious

意殇

| 2008年6月23日星期一

4:30,我糊里糊涂的自然醒,一看耳机已经不在耳边,我知道我已经晚了。我得马上下床看球。

90:03,90分钟的比赛马上就要结束了,0:0。即使此时我的大脑再混沌,我也预见到了这场比赛恐怕要打加时,乃至点球。一场极其丑陋的加时,双方几乎没有在进攻上花费脑细胞,沉闷无趣的30分钟,连射正都没有几次的两只地中海球队走向了点球决战

随着小法踢出的皮球钻进网窝,我的意大利回家了,以一种惨烈丑陋的方式。

说实话,我对这支意大利感到无奈。托尼一个赛季三十几个联赛进球怎么感觉都是假的,曾经的意甲德甲最佳射手消失了,我们看到的只是一个永远找不到球门的托尼,一个迷失在后卫群中的托尼,只能让人无奈的悲呼:“Luca,你脚上穿的难道是Air Force One么?”

即使他在皇马很不济,即使被称为最水的欧洲足球先生与世界足球先生,卡纳瓦罗是后防线上的作用仍然是无可比拟的,他的上抢永远是他的搭档的最好的镇定剂,不管是内斯塔还是马特拉济。这次没有卡纳瓦罗的欧洲杯,瞬间便把意大利后防线的巨大问题完全暴露了出来:80一代,你们谁能顶替老队长?巴尔扎利?不要忘了这里不是FM,巴尔扎利也不是FM里面那个稳定强壮的后防铁塔。费拉里?除了平庸以外谁还能找到另外一个词形容这个曾经的希望之星?

还好,我们基耶利尼,可边可中的尤文后卫让我想到了马尔蒂尼。不过看了比赛之后,我发现他变了,现在的他比起打边卫的时候更强大,或许从特点看,他不是下一个马尔蒂尼,但是我们已经清晰的看到了一个年轻了11岁的卡纳瓦罗正在崛起。凶狠的上抢,准确的卡位,强壮的身体,出色的意识,还有身高,还能打边路,活脱脱一个卡纳瓦罗的加强版嘛。

赛后,我们看到了一个泪流满面的皮尔洛,这次他的缺阵是意大利最大的损失,小组赛意大利就是靠着他、基耶利尼和布冯的出色发挥才跌跌撞撞的走入淘汰赛,可他却黄牌停赛了。全罗马中场让我们看到了一个有跑动、有抢断、有激情、有活力的意大利中场,但总是缺少一些头脑与创意。皮尔洛的缺阵是意大利的致命伤。他又一次向全世界证明了:皮尔洛,不仅仅是米兰找不到他的替身,意大利也没有,全世界只有一个皮尔洛,或许他真的是上帝的恩赐吧。

德罗西,或许多纳多尼把他作为皮尔洛的应急替代品的确是为难他了,他只是一个出色的意大利全能中场,但他不是皮尔洛。他有身体,有远射,跑动积极防守到位,技术在意大利的中场也是很优异的,但是他还远远不是皮尔洛,或许他还是缺少一些皮尔洛元素吧。但是我相信德罗西会是未来几年内意大利的中场核心。佩罗塔仍然是个工兵性前腰,阿奎拉尼则没有踢出在罗马的水平,或许斯帕莱蒂的战术可以让他们三个都踢出皮尔洛的味道,但是国家队没有斯帕莱蒂,他们也还不是皮尔洛。

坚毅如钢的表情,寒冷如冰的目光,我们又看到了最好的布冯,可是他面对的是一只完全扭曲的意大利,以及一个更神奇的圣卡西。意大利人不会踢点球,可是传统意义上,西班牙更不会。不过圣卡西的存在似乎就是为了把不可能变成可能。或许就是命吧。

再见了,意大利,我的无倾向欧洲杯也要开幕了

如果你喜欢本文,把它分享到 Twitter / 校内 / 鲜果 / Digg
或者把它收藏到 Delicious

C#中的多态:visual、override 与 new

| 2008年6月7日星期六

{ZHUAXIAead3dc42408ec383161c818b0f5bad3eUnion}

今天金山笔试,出了这么一道题,做题的途中忽然想到了Blog好久不更新了。。。。汗,溜号啊

[coolcode lang="cpp"]
public abstract class A
{
public A()
{
Console.WriteLine('A');
}
public virtual void Fun()
{
Console.WriteLine("A.Fun()");
}
}
public class B: A
{
public B()
{
Console.WriteLine('B');
}
public new void Fun()
{
Console.WriteLine("B.Fun()");
}
public static void Main()
{
A a = new B();
a.Fun();
}
}
[/coolcode]

结果是

A
B
A.Fun()

结果倒是显而易见,不过我想起刚看C#时,对于visual\override\new的区别来着,当时就有点糊涂。

MSDN的解释是这样的
在 C# 中,派生类可以包含与基类方法同名的方法。

  • 基类方法必须定义为 virtual。

  • 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。

  • 如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。

  • 如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法。

  • 可以从派生类中使用 base 关键字调用基类方法。

  • override、virtual 和 new 关键字还可以用于属性、索引器和事件中。



当时是相当的糊涂了。啥玩意,多态咋还出来一个new呢

后来慢慢理解了。。。

visual是override的前提与基础,既只有在基类的函数是visual的情况下,你才能在子类中override,否则编译会报错

new则是跟基类没多大关系的,除了名字相同之外。它独立于基类,相当于在子类中添加了一个新的方法。

我写了一个更合适的例子

[coolcode lang="cpp"]
public abstract class A
{
public void F()
{
System.Console.WriteLine("A.F");
}
public virtual void G()
{
System.Console.WriteLine("A.G");
}
}
public class B:A
{
public new void F()
{
System.Console.WriteLine("B.F");
}
public new void G()
{
System.Console.WriteLine("B.G");
}
}
public class C:A
{
public new void F()
{
System.Console.WriteLine("C.F");
}
public override void G()
{
System.Console.WriteLine("C.G");
}
}
class Program
{
static void Main(string[] args)
{
B b = new B();
C c = new C();
A a = b;
A d = c;
a.F();
a.G();
b.F();
b.G();
c.F();
c.G();
d.F();
d.G();
Console.Read();
}
}
[/coolcode]

结果如下
A.F
A.G
B.F
B.G
C.F
C.G
A.F
C.G

值得注意的是d的调用,因为C的G()实现是override,因此c.G()隐藏了A.G(),输出结果就是c的输出结果,而b的G()实现是new,独立于基类,因此A.G()并没有被覆盖,a调用是仍然是调用的的A自己的G(), b调用的是new G().

如果你喜欢本文,把它分享到 Twitter / 校内 / 鲜果 / Digg
或者把它收藏到 Delicious

C#实现支持插件与二次开发的应用程序编写

| 2008年5月23日星期五

CreditDKMILAN副本这两天一直在研究这个插件功能的实现,总结一些心得吧。

首先是应该定义插件应该实现的接口,接口里面是插件需要实现的功能与提供的内容。我是这么设计的:

首先是建立一个新的类库,用于把我们支持的插件的类型都以接口的形式放进去。比如我现在为我的Service Master设计了以下几个插件类型:外观插件,功能插件,系统信息插件,其他类型插件。目前接口设计如下



然后在原有的软件项目(ServiceMaster)中添加了一个插件检测的类,这个类用于检测已经放到Plugin文件夹下的插件。
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Collections;
namespace ServiceMaster
{
public static class PluginCheck
{
public static IPluginMenu[] getAllPluginsMenu()
{
IPluginInfo[] plugins = getAllPluginsInfo();
List menus = new List();
foreach (IPluginInfo plugin in plugins)
{
if (plugin is IPluginMenu)
menus.Add((IPluginMenu)plugin);
}
return menus.ToArray();
}
public static IPluginInfo[] getAllPluginsInfo()
{
if (Directory.Exists(Directory.GetCurrentDirectory() + @"\Plugin"))
{
string[] files = Directory.GetFiles(Directory.GetCurrentDirectory() + @"\Plugin");
List dlls = new List();
foreach(string file in files)
{
FileInfo info = new FileInfo(file);
if (info.Extension == ".dll")
dlls.Add(getPluginClass(info.Name, "PluginInfo"));
}
return dlls.ToArray();
}
else
{
Directory.CreateDirectory(Directory.GetCurrentDirectory() + @"\Plugin");
return new IPluginInfo[0];
}
}
public static IPluginInfo getPluginClass(string filename,string className)
{
Assembly ass = null;
try
{
ass = Assembly.LoadFrom(@"plugin\" + filename);
}
catch (BadImageFormatException)
{
return null;
}
string nspace=System.IO.Path.GetFileNameWithoutExtension(filename);
Type search = ass.GetType(nspace + "." + className);
if (search==null)
return null;
Object o = Activator.CreateInstance(search);
IPluginInfo info = (IPluginInfo)o;
return info;
}
}
}
 
然后的工作就是就是编写插件了。

得益于.Net平台的CLR,在VS上写出的所有的类库都是可以用的,不管你是用C++还是C#还是其他

就以C#为例说一下写一个插件的步骤


  • 建一个类库

  • 在引用里面添加我们写好的PluginSupport.dll

  • 然后建一个类,类名一定是PluginInfo.cs。记得一定加上using ServcieMaster

  • 然后让这个类实现上面的任意一个或者多个继承于IPluginInfo的接口(也可以只实现IPluginSysInfo,但是那样的话我的ServiceMaster只能认出来是一个插件,但是没有实际功能)

  • 完善功能

  • 编译,生成DLL

  • 把生成的插件放到ServiceMaster的Plugin文件夹下

  • 运行ServiceMaster


这是一个示例的插件
using System;
using System.Collections.Generic;
using System.Text;
using ServiceMaster;
using System.Reflection;

namespace testPlugin
{
public class PluginInfo:IPluginMenu
{
#region IPluginInfo 成员

string IPluginInfo.AutherWebUrl
{
get
{
return "http://dkmilan.72pines.com";
}
}

string IPluginInfo.Author
{
get
{
return "DKMILAN";
}
}

string IPluginInfo.Name
{
get
{
return "TestPlugin";
}
}

string IPluginInfo.Version
{
get { return "1.0.0.0"; }
}
#endregion

#region IPluginMenu 成员

System.Windows.Forms.ToolStripMenuItem IPluginMenu.PluginMenu
{
get
{
System.Windows.Forms.ToolStripMenuItem MenuOne = new System.Windows.Forms.ToolStripMenuItem();
System.Windows.Forms.ToolStripMenuItem MenuTwo = new System.Windows.Forms.ToolStripMenuItem();
System.Windows.Forms.ToolStripMenuItem topMenu = new System.Windows.Forms.ToolStripMenuItem();
//
// MenuOne
//
MenuOne.Name = "MenuOne";
MenuOne.Size = new System.Drawing.Size(148, 22);
MenuOne.Text = "Hello!";
MenuOne.Click += new System.EventHandler(MenuOne_Click);
//
// MenuTwo
//
MenuTwo.Name = "MenuTwo";
MenuTwo.Size = new System.Drawing.Size(148, 22);
MenuTwo.Text = "Hello 2~";
MenuTwo.Click += new System.EventHandler(MenuTwo_Click);
//
// topMenu
//
topMenu.Name = "topMenu";
topMenu.Size = new System.Drawing.Size(148, 22);
topMenu.Text = "插件菜单";
//
topMenu.DropDownItems.Add(MenuOne);
topMenu.DropDownItems.Add(MenuTwo);
return topMenu;
}
}

#endregion

private void MenuOne_Click(object sender, EventArgs e)
{
System.Windows.Forms.MessageBox.Show("Enjoy ServiceMaster!");
}
private void MenuTwo_Click(object sender, EventArgs e)
{
System.Windows.Forms.MessageBox.Show("My Plugin!");
}
}
}

如果你喜欢本文,把它分享到 Twitter / 校内 / 鲜果 / Digg
或者把它收藏到 Delicious

汶川的背后

| 2008年5月19日星期一




汶川是一面镜子,我们既看到了人性的善良也看到了人性的丑恶
汶川是一面镜子,我们既看到了生命的坚强也看到了生命的脆弱
汶川是一面镜子,我们既看到了民族的团结也看到了民族的劣根

如果你喜欢本文,把它分享到 Twitter / 校内 / 鲜果 / Digg
或者把它收藏到 Delicious