2012-07-18 33 views
21

Tôi có một lớp học Thing đó là ngầm castable từ một string. Khi tôi gọi phương thức với tham số Thing trực tiếp, diễn viên từ string đến Thing được thực hiện chính xác.Làm thế nào để đúc hoàn toàn trên một phương pháp phản ánh cuộc gọi

Tuy nhiên nếu tôi sử dụng phản ánh để gọi cùng một phương pháp nó ném ngoại lệ

System.ArgumentException : Object of type 'System.String' cannot be 
converted to type 'Things.Program+Thing'. 

Có thể có một lý do chính đáng cho điều này, nhưng tôi không thể hình dung nó ra. Có ai đó có một ý tưởng làm thế nào để có được điều này làm việc bằng cách sử dụng sự phản ánh?

namespace Things 
{ 
    class Program 
    { 
     public class Thing 
     { 
      public string Some; 

      public static implicit operator Thing(string s) 
      { 
       return new Thing {Some = s}; 
      } 
     } 

     public void showThing(Thing t) 
     { 
      Console.WriteLine("Some = " + t.Some); 
     } 

     public void Main() 
     { 
      showThing("foo"); 
      MethodInfo showThingReflected = GetType().GetMethod("showThing"); 
      showThingReflected.Invoke(this, new dynamic[] {"foo"}); 
     } 
    } 
} 

Meta: Xin vui lòng, không thảo luận tại sao việc truyền hoặc phản chiếu ngầm là xấu.

+4

Tắt đầu của tôi, tôi sẽ đặt cược bởi vì (tôi nghĩ và sửa tôi nếu tôi sai) mà việc truyền ngầm là cú pháp đường cho trình biên dịch. Rằng các cuộc gọi thực tế đến phương pháp đúc được kết nối tại thời gian biên dịch. EDIT: Bạn có cần phải có một số cách chung chung của gọi trình chuyển đổi tiềm ẩn cho bất kỳ chuyển đổi đối tượng? Hay đây là một trường hợp đặc biệt mà bạn muốn sẵn sàng nhắm mục tiêu một phương thức tĩnh riêng biệt hoặc một số lời gọi phản chiếu khác đến một phương pháp được xác định trước hoặc có lẽ là một nhà xây dựng chuyên ngành? –

+0

câu hỏi tương tự [ở đây] (http://stackoverflow.com/questions/4501469/c-sharp-implicit-cast-overloading-and-reflection-problem) –

+2

Truyền ngầm là không thể qua phản xạ nhưng bạn có thể sử dụng [TypeConvertor] (http://msdn.microsoft.com/en-us/library/98bbex99.aspx#the_typeconverter_class). –

Trả lời

1

Trong trường hợp cụ thể này, bạn có thể làm cho việc chuyển đổi qua kiểu mảng, đó là

showThingReflected.Invoke(this, new Thing[] {"foo"}); 

nhưng đó là một loại "gian lận". Nói chung, bạn không thể mong đợi Invoke để xem xét người dùng được xác định implicit operator do người dùng xác định. Chuyển đổi này phải là thời gian biên dịch phỏng đoán.

9

Bí quyết là để nhận ra rằng trình biên dịch tạo ra một phương pháp tĩnh đặc biệt gọi là op_Implicit cho nhà điều hành chuyển đổi ngầm của bạn.

object arg = "foo"; 

// Program.showThing(Thing t) 
var showThingReflected = GetType().GetMethod("showThing"); 

// typeof(Thing) 
var paramType = showThingReflected.GetParameters() 
            .Single() 
            .ParameterType; 

// Thing.implicit operator Thing(string s) 
var converter = paramType.GetMethod("op_Implicit", new[] { arg.GetType() }); 

if (converter != null) 
    arg = converter.Invoke(null, new[] { arg }); // Converter exists: arg = (Thing)"foo"; 

// showThing(arg) 
showThingReflected.Invoke(this, new[] { arg }); 
+0

rực rỡ !!!!!!!!!!!!! – denfromufa

+0

đây là một câu trả lời tương tự khác: http://stackoverflow.com/a/32025393/2230844 – denfromufa

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