每周源代码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是一个独立思考的家伙,他很强大。他还加入了一个类图解:

clip_image002

我强烈建议你们去看下。我觉得一个这么聪敏的类会是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);

        }

    }

}

如果找到任何很酷的阅读源代码的链接,请随时发给我。


Comments (0)

Skip to main content