程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> c#擴展方法奇思妙用高級篇四:對擴展進行分組管理(3)

c#擴展方法奇思妙用高級篇四:對擴展進行分組管理(3)

編輯:關於C語言

方法三將所有的擴展精簡為一個As<T>!是的,我們僅需要As<T>這一個擴展!T為一接口,通過輸入不同的T,展示相應的擴展。這樣又解決了擴展組的泛濫問題,先看下實現一個新的擴展組需要寫什麼代碼,先看左圖的代碼:

1 public interface IConvertableString : IExtension<string> { }
2
3 public static class ConvertableString
4 {
5  public static bool IsInt(this IConvertableString s)
6  {
7   int i; return int.TryParse(s.GetValue(), out i);
8  }
9  public static bool IsDateTime(this IConvertableString s)
10  {
11   DateTime d; return DateTime.TryParse(s.GetValue(), out d);
12  }
13
14 public static int ToInt(this IConvertableString s)
15 {
16  return int.Parse(s.GetValue());
17 }
18
19  public static DateTime ToDateTime(this IConvertableString s)
20  {
21   return DateTime.Parse(s.GetValue());
22  }
23 }

首先定義一個接口IConvertableString,它繼承泛型接口IExtension<T>(我定義的一個接口,稍後給出),因為是對string類作擴展,所以泛型參數為string。IConvertableString只需要一個空架子。然後再編寫一個擴展類,所有的方法擴展在IConvertableString接口上。

再來看右圖IRegexableString的代碼:

1 public static class RegexableString
2 {
3  public static bool IsMatch(this IRegexableString s, string pattern)
4  { throw new NotImplementedException(); }
5   public static string Match(this IRegexableString s, string pattern)
6  { throw new NotImplementedException(); }
7   public static string Relplace(this IRegexableString s, string pattern, MatchEvaluator evaluator)
8  { throw new NotImplementedException(); }
9 }

與上一個一樣,也是先定義一個空接口,再定義一個擴展類,將方法擴展在空接口上。

有一點注意一下,擴展的實現中都要使用GetValue獲取原始字符串的值。

最後給出IExtension<T>接口及As<T>擴展的實現: 

1 public interface IExtension<V>
2 {
3  V GetValue();
4 }
5
6 public static class ExtensionGroup
7 {
8  private static Dictionary<Type, Type> cache = new Dictionary<Type, Type>();
9
10  public static T As<T>(this string v) where T : IExtension<string>
11  {
12            return As<T, string>(v);
13  }
14
15  public static T As<T, V>(this V v) where T : IExtension<V>
16  {
17   Type t;
18   Type valueType = typeof(V);
19   if (cache.ContainsKey(valueType))
20   {
21    t = cache[valueType];
22   }
23   else
24   {
25    t = CreateType<T, V>();
26    cache.Add(valueType, t);
27   }
28   object result = Activator.CreateInstance(t, v);
29   return (T)result;
30  }
31  // 通過反射發出動態實現接口T
32  private static Type CreateType<T, V>() where T : IExtension<V>
33  {
34   Type targetInterfaceType = typeof(T);
35   string generatedClassName = targetInterfaceType.Name.Remove(0, 1);
36   //
37   AssemblyName aName = new AssemblyName("ExtensionDynamicAssembly");
38   AssemblyBuilder ab =
39   AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
40   ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
41   TypeBuilder tb = mb.DefineType(generatedClassName, TypeAttributes.Public);
42   //實現接口
43   tb.AddInterfaceImplementation(typeof(T));
44   //value字段
45   FieldBuilder valueFiled = tb.DefineField("value", typeof(V), FIEldAttributes.Private);
46   //構造函數
47   ConstructorBuilder ctor = tb.DefineConstructor(MethodAttributes.Public,
48   CallingConventions.Standard, new Type[] { typeof(V) });
49   ILGenerator ctor1IL = ctor.GetILGenerator();
50   ctor1IL.Emit(OpCodes.Ldarg_0);
51   ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
52   ctor1IL.Emit(OpCodes.Ldarg_0);
53   ctor1IL.Emit(OpCodes.Ldarg_1);
54   ctor1IL.Emit(OpCodes.Stfld, valueFiled);
55   ctor1IL.Emit(OpCodes.Ret);
56   //GetValue方法
57   MethodBuilder getValueMethod = tb.DefineMethod("GetValue",
58   MethodAttributes.Public | MethodAttributes.Virtual, typeof(V), Type.EmptyTypes);
59   ILGenerator numberGetIL = getValueMethod.GetILGenerator();
60   numberGetIL.Emit(OpCodes.Ldarg_0);
61   numberGetIL.Emit(OpCodes.Ldfld, valueFiled);
62   numberGetIL.Emit(OpCodes.Ret);
63   //接口實現
64   MethodInfo getValueInfo = targetInterfaceType.GetInterfaces()[0].GetMethod("GetValue");
65   tb.DefineMethodOverride(getValueMethod, getValueInfo);
66   //
67   Type t = tb.CreateType();
68   return t;
69  }
70 }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved