每周源代码8
[原文发表地址]The Weekly Source Code 8
[原文发表时间] 2007-10-19 07:04 AM
沿袭我一贯的要求阅读源代码以开发出更好的程序,我将为大家呈上每周不限数系列“每周源代码”的第八篇,此后我也将继续附上其他的文章。这是我这周在读的我很欣赏的一些源代码。
Vista 电池节约装置是一个简单有趣的小应用,在你用电池运行时关闭Aero和工具条。源文件可以在CodePlex上找到。他在Windows上为电源通知注册了一个应用。Windows在系统电源状态转换时会给他的应用发出一个窗口消息。
//In the main WinForm, he overrides the WndProc
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == PowerMngr.WM_POWERBROADCAST)
{
PowerMngr.GetManager().PowerSettingChange(m);
}
}
//Earlier he selects the messages he's interested in.
internal void RegisterForPowerNotifications(IntPtr hwnd)
{
hPowerSrc = RegisterPowerSettingNotification(hwnd,
ref GUID_ACDC_POWER_SOURCE,
DEVICE_NOTIFY_WINDOW_HANDLE);
hBattCapacity = RegisterPowerSettingNotification(hwnd,
ref GUID_BATTERY_PERCENTAGE_REMAINING,
DEVICE_NOTIFY_WINDOW_HANDLE);
hMonitorOn = RegisterPowerSettingNotification(hwnd,
ref GUID_MONITOR_POWER_ON,
DEVICE_NOTIFY_WINDOW_HANDLE);
hPowerScheme = RegisterPowerSettingNotification(hwnd,
ref GUID_POWERSCHEME_PERSONALITY,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
[DllImport(@"User32", SetLastError = true, EntryPoint = "RegisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr RegisterPowerSettingNotification(
IntPtr hRecipient,
ref Guid PowerSettingGuid,
Int32 Flags);
Patrick Smacchia今天发布了一款强类型路径库。大家都知道Patrick是一个独立思考的家伙,他很强大。他还加入了一个类图解:
我强烈建议你们去看下。我觉得一个这么聪敏的类会是BCL的一个很不错的附加。这里提供一些体现库用途的测试代码。注意Asserts中的!。在我看来,他们不是很明显,以通常使用的是==false。我觉得这个读起来很简单。
//
// Path string validation
//
string reason;
Debug.Assert(PathHelper.IsValidAbsolutePath(@"C:\Dir2\Dir1", out reason));
Debug.Assert(!PathHelper.IsValidAbsolutePath(@"C:\..\Dir1", out reason));
Debug.Assert(!PathHelper.IsValidAbsolutePath(@".\Dir1", out reason));
Debug.Assert(!PathHelper.IsValidAbsolutePath(@"1:\Dir1", out reason));
Debug.Assert(PathHelper.IsValidRelativePath(@".\Dir1\Dir2", out reason));
Debug.Assert(PathHelper.IsValidRelativePath(@"..\Dir1\Dir2", out reason));
Debug.Assert(PathHelper.IsValidRelativePath(@".\Dir1\..\Dir2", out reason));
Debug.Assert(!PathHelper.IsValidRelativePath(@".\Dir1\..\..\Dir2", out reason));
Debug.Assert(!PathHelper.IsValidRelativePath(@"C:\Dir1\Dir2", out reason));
这周我跟John Lam聊天时,他说:“顺便提一下,我对C# 3.0很有兴趣,这真的是一个很好的语言。我今天写了一个应用,把所有我们实践的Ruby方法都转储到了一个YAML文件。”这周晚些时候我会将它放到RubyForge上,这里先提供一部分片段。这有大概100行,阅读这些需要花些时间。这是一个简单且很好的方法来使用LINQ很简单,是也很好的方法来使用针对LINQ的反射,而且使用生成的扩展方法也很简洁方便。从底部的Main()方法开始读起,然后用你的方式看看。当然它可以更简短,不过这样做他好像是依照他自己的审美感去做到平衡。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Ruby;
using Ruby.Extensions;
using Microsoft.Scripting.Utils;
using Ruby.Runtime;
namespace IronRuby.Library.Scanner {
static class ExtensionMethods {
public static IEnumerable<T> SelectCustomAttributes<T>(this Type type) where T : Attribute {
return type.GetCustomAttributes(typeof(T), false).Cast<T>();
}
public static IEnumerable<T> SelectCustomAttributes<T>(this MethodInfo method) where T : Attribute {
return method.GetCustomAttributes(typeof(T), false).Cast<T>();
}
}
class RubyClassInfo {
public Type ClrType { get; set; }
public delegate void Block(IEnumerable<RubyMethodAttribute> methods);
public string Name {
get { return ClrType.SelectCustomAttributes<RubyClassAttribute>().First().Name ?? ClrType.Name; }
}
private Type LookupExtensionModuleType(IncludesAttribute attr) {
Type includedType;
Program.ExtensionModules.TryGetValue(attr.Type, out includedType);
return includedType ?? attr.Type;
}
private void GetMethodNames(Type t, Block accumulate) {
var methods = (from m in t.GetMethods()
where m.IsDefined(typeof(RubyMethodAttribute), false)
select m.SelectCustomAttributes<RubyMethodAttribute>().First());
accumulate(methods);
foreach (IncludesAttribute attr in t.SelectCustomAttributes<IncludesAttribute>())
GetMethodNames(LookupExtensionModuleType(attr), accumulate);
}
private IEnumerable<string> GetMethodNames(RubyMethodAttributes methodType) {
var result = new List<string>();
GetMethodNames(ClrType, methods =>
result.AddRange((from m in methods
where m.MethodAttributes == methodType
select m.Name).Distinct()));
result.Sort();
return result;
}
public IEnumerable<string> InstanceMethods {
get { return GetMethodNames(RubyMethodAttributes.PublicInstance); }
}
public IEnumerable<string> SingletonMethods {
get { return GetMethodNames(RubyMethodAttributes.PublicSingleton); }
}
}
class Program {
static IEnumerable<RubyClassInfo> GetRubyTypes(Assembly a) {
return from rci in
(from t in a.GetTypes()
where t.IsDefined(typeof(RubyClassAttribute), false)
&& !t.IsDefined(typeof(RubyExtensionModuleAttribute), false)
select new RubyClassInfo { ClrType = t })
orderby rci.Name
select rci;
}
static Dictionary<Type, Type> GetExtensionModules(Assembly a) {
var modules = from t in a.GetTypes()
where t.IsDefined(typeof(RubyExtensionModuleAttribute), false)
select new { Type = t, Attribute = t.SelectCustomAttributes<RubyExtensionModuleAttribute>().First() };
var result = new Dictionary<Type, Type>();
foreach(var m in modules)
result[m.Attribute.Extends] = m.Type;
return result;
}
const string RubyAssembly = @"Ruby, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
internal static Dictionary<Type, Type> ExtensionModules;
static void DumpMethods(IEnumerable<RubyClassInfo> types, Func<RubyClassInfo, IEnumerable<string>> getMethods) {
foreach (RubyClassInfo rci in types) {
Console.WriteLine("{0}:", rci.Name);
foreach (string methodName in getMethods(rci))
Console.WriteLine(" - {0}", methodName);
}
}
static void Main(string[] args) {
var name = new AssemblyName(RubyAssembly);
var a = Assembly.Load(name);
ExtensionModules = GetExtensionModules(a);
var types = GetRubyTypes(a);
DumpMethods(types, t => t.InstanceMethods);
DumpMethods(types, t => t.SingletonMethods);
}
}
}
如果找到任何很酷的阅读源代码的链接,请随时发给我。