2012-04-13 43 views
5

tôi đã chọc vào lắp ráp Microsoft.Practices.Prism sử dụng phản xạ và đã xem qua các định nghĩa sau đây cho các nhà xây dựng của DelagateCommand:C# Constructor từ khóa cơ sở

public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod) 
    : base(action, func) 
{ 
    Action<object> action = null; 
    Func<object, bool> func = null; 
    if (action == null) 
    { 
     action = o => executeMethod(); 
    } 
    if (func == null) 
    { 
     func = o => canExecuteMethod(); 
    } 
    if ((executeMethod == null) || (canExecuteMethod == null)) 
    { 
     throw new ArgumentNullException(
      "executeMethod", 
      Resources.DelegateCommandDelegatesCannotBeNull); 
    } 
} 

Mã này không biên dịch từ : base(action, func) điểm để hai người đầu tiên biến trong ctor.

Có thể sao chép loại hành vi này không? có lẽ bằng cách sử dụng các phương pháp anon?

Cảm ơn bạn đã nhập trước.

Reflector IL cho phương pháp này:

.method public hidebysig specialname rtspecialname instance void .ctor(class [mscorlib]System.Action executeMethod, class [mscorlib]System.Func`1<bool> canExecuteMethod) cil managed 
{ 
    .maxstack 5 
    .locals init (
     [0] class [mscorlib]System.Action`1<object> action, 
     [1] class [mscorlib]System.Func`2<object, bool> func, 
     [2] class Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6 class2) 
    L_0000: ldnull 
    L_0001: stloc.0 
    L_0002: ldnull 
    L_0003: stloc.1 
    L_0004: newobj instance void Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::.ctor() 
    L_0009: stloc.2 
    L_000a: ldloc.2 
    L_000b: ldarg.1 
    L_000c: stfld class [mscorlib]System.Action Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::executeMethod 
    L_0011: ldloc.2 
    L_0012: ldarg.2 
    L_0013: stfld class [mscorlib]System.Func`1<bool> Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::canExecuteMethod 
    L_0018: ldarg.0 
    L_0019: ldloc.0 
    L_001a: brtrue.s L_0029 
    L_001c: ldloc.2 
    L_001d: ldftn instance void Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::<.ctor>b__2(object) 
    L_0023: newobj instance void [mscorlib]System.Action`1<object>::.ctor(object, native int) 
    L_0028: stloc.0 
    L_0029: ldloc.0 
    L_002a: ldloc.1 
    L_002b: brtrue.s L_003a 
    L_002d: ldloc.2 
    L_002e: ldftn instance bool Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::<.ctor>b__3(object) 
    L_0034: newobj instance void [mscorlib]System.Func`2<object, bool>::.ctor(object, native int) 
    L_0039: stloc.1 
    L_003a: ldloc.1 
    L_003b: call instance void Microsoft.Practices.Prism.Commands.DelegateCommandBase::.ctor(class [mscorlib]System.Action`1<object>, class [mscorlib]System.Func`2<object, bool>) 
    L_0040: ldloc.2 
    L_0041: ldfld class [mscorlib]System.Action Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::executeMethod 
    L_0046: brfalse.s L_0050 
    L_0048: ldloc.2 
    L_0049: ldfld class [mscorlib]System.Func`1<bool> Microsoft.Practices.Prism.Commands.DelegateCommand/<>c__DisplayClass6::canExecuteMethod 
    L_004e: brtrue.s L_0060 
    L_0050: ldstr "executeMethod" 
    L_0055: call string Microsoft.Practices.Prism.Properties.Resources::get_DelegateCommandDelegatesCannotBeNull() 
    L_005a: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string, string) 
    L_005f: throw 
    L_0060: ret 
} 

Ngoài ra sau khi nhìn vào thực tế source code tại CodePlex định nghĩa phương pháp là như sau:

public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod) 
      : base((o) => executeMethod((T)o), (o) => canExecuteMethod((T)o)) 
     { 
      if (executeMethod == null || canExecuteMethod == null) 
       throw new ArgumentNullException("executeMethod", Resources.DelegateCommandDelegatesCannotBeNull); 

#if !WINDOWS_PHONE 
      Type genericType = typeof(T); 

      // DelegateCommand allows object or Nullable<>. 
      // note: Nullable<> is a struct so we cannot use a class constraint. 
      if (genericType.IsValueType) 
      { 
       if ((!genericType.IsGenericType) || (!typeof(Nullable<>).IsAssignableFrom(genericType.GetGenericTypeDefinition()))) 
       { 
        throw new InvalidCastException(Resources.DelegateCommandInvalidGenericPayloadType); 
       } 
      } 
#endif 
     } 

Trả lời

6

Tôi nghĩ rằng đây là lẽ chỉ là một phản xạ lỗi, cố gắng để đại diện cho cách mà các đại biểu ủng hộ cho lambdas được lưu trữ. Mã thực có nhiều khả năng nhất là:

: base(o => executeMethod(), o => canExecuteMethod()) 

Bạn có IL không?


Chỉnh sửa: Hmmm ... Tôi không thể lặp lại điều đó. Có hai tùy chọn khác, mặc dù: trong cả C++ và IL bạn có thể làm khá nhiều thứ. Mã đó có vẻ ... funky, mặc dù.

+1

Có, đó là lệnh gọi cơ bản thực tế theo nguồn (ngoại trừ nguồn có dấu ngoặc đơn thừa: P) ... trong PrismLibrary \ Desktop \ Prism \ Commands \ DelegateCommand.cs – BoltClock

+0

@ BoltClock'saUnicorn trong trường hợp đó, bộ phản xạ của tôi phải khác với OP - tôi nhận được kết quả đầu ra đúng ... trừ khi nó đang táo bạo và thăm dò của tôi .pdb –

+0

Rõ ràng là một lỗi phản xạ nhưng mã này trông thực sự funcky! –

0

IMHO, đó là lỗi của Reflector. Tại sao bạn không nhìn vào mã nguồn của Prism?

Các vấn đề liên quan