2012-09-02 13 views
71

Nếu tôi có:Làm thế nào để đưa Object vào loại thực tế của nó?

void MyMethod(Object obj) { ... } 

Làm thế nào tôi có thể đúc obj để loại thực tế của nó là gì?

+2

Loại này có biết thời gian biên dịch không? – psubsee2003

+1

Và bạn mong đợi gì để đạt được điều này? Hãy cho chúng tôi biết những gì bạn đang cố gắng đạt được, thay vì cách bạn mong đợi đạt được nó. –

+0

@JonSkeet: Tôi muốn có thể gọi một hàm từ đối tượng. Hiện tại 'obj.MyFunction();' không biên dịch, mặc dù tôi biết rằng đối tượng thực sự có hàm đó. –

Trả lời

117

Nếu bạn biết loại thực tế, sau đó chỉ cần:

SomeType typed = (SomeType)obj; 
typed.MyFunction(); 

Nếu bạn không biết loại thực tế, sau đó: không thực sự, Không. Bạn sẽ phải thay vì sử dụng một trong số:

  • phản ánh
  • thực hiện một giao diện nổi tiếng
  • động

Ví dụ:

// reflection 
obj.GetType().GetMethod("MyFunction").Invoke(obj, null); 

// interface 
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction 
foo.MyFunction(); 

// dynamic 
dynamic d = obj; 
d.MyFunction(); 
+0

Cú pháp tương đương trong Swift là gì? – Rao

+1

Nevermind, tìm thấy 'as' cho chức năng typecasting và' type (of: ClassName) 'để kiểm tra kiểu cá thể. – Rao

0

Đúc để loại thực tế rất dễ dàng:

void MyMethod(Object obj) { 
    ActualType actualyType = (ActualType)obj; 
} 
+4

rất vui ... – Steve

+1

Điều này là phi lý. Bạn thực sự không biết loại thực tế. Làm thế nào bạn có nghĩa vụ phải làm điều đó? –

28

Tôi không nghĩ bạn có thể (không phải không phản ánh), bạn cũng nên cung cấp một loại cho chức năng của mình:

void MyMethod(Object obj, Type t) 
{ 
    var convertedObject = Convert.ChangeType(obj, t); 
    ... 
} 

UPD:

Điều này có thể làm việc cho bạn:

void MyMethod(Object obj) 
{ 
    if (obj is A) 
    { 
     A a = obj as A; 
     ... 
    } 
    else if (obj is B) 
    { 
     B b = obj as B; 
     ... 
    } 
} 
+1

Điều này thực sự là một câu trả lời vô ích, không xứng đáng với số phiếu bầu. Phản ánh của một đối tượng của đối tượng kiểu sẽ không mang lại "loại thực tế" của đối tượng, như được hỏi bởi OP. Ngoài ra, logic MyMethod của bạn là thiếu sót vì obj có thể thuộc loại A và nó cũng có thể thuộc loại B. Logic của bạn không cung cấp "loại thực tế" (như OP được yêu cầu) - nó cung cấp loại tương thích và không nhất thiết loại mong muốn tại đó. – Jazimov

0
Implement an interface to call your function in your method 
interface IMyInterface 
{ 
void MyinterfaceMethod(); 
} 

IMyInterface MyObj = obj as IMyInterface; 
if (MyObj != null) 
{ 
MyMethod(IMyInterface MyObj); 
} 
0

Nếu phương pháp MyFunction() của bạn được xác định duy nhất trong một lớp (và con cháu của nó), hãy thử

void MyMethod(Object obj) 
{ 
    var o = obj as MyClass; 
    if (o != null) 
     o.MyFunction(); 
} 

Nếu bạn có một số lượng lớn trong các lớp học không liên quan xác định các chức năng mà bạn muốn gọi, bạn nên xác định một giao diện và làm cho lớp học của bạn xác định giao diện mà:

interface IMyInterface 
{ 
    void MyFunction(); 
} 

void MyMethod(Object obj) 
{ 
    var o = obj as IMyInterface; 
    if (o != null) 
     o.MyFunction(); 
} 
0

Cast nó để loại thực sự của nó nếu bây giờ bạn loại ví dụ nó được định hướng từ lớp có tên abc. Bạn có thể gọi hàm theo cách này:

(abc)(obj)).MyFunction(); 

nếu bạn không biết chức năng có thể được thực hiện theo cách khác. Không phải lúc nào cũng dễ dàng. Nhưng bạn có thể tìm thấy nó theo một cách nào đó bằng chữ ký của nó. Nếu đây là trường hợp của bạn, bạn nên cho chúng tôi biết.

0

Trong trường hợp của tôi, AutoMapper hoạt động tốt.

AutoMapper có thể ánh xạ đến/từ đối tượng năng động mà không cần bất kỳ cấu hình rõ ràng:

public class Foo { 
    public int Bar { get; set; } 
    public int Baz { get; set; } 
} 
dynamic foo = new MyDynamicObject(); 
foo.Bar = 5; 
foo.Baz = 6; 

Mapper.Initialize(cfg => {}); 

var result = Mapper.Map<Foo>(foo); 
result.Bar.ShouldEqual(5); 
result.Baz.ShouldEqual(6); 

dynamic foo2 = Mapper.Map<MyDynamicObject>(result); 
foo2.Bar.ShouldEqual(5); 
foo2.Baz.ShouldEqual(6); 

Tương tự, bạn có thể ánh xạ trực tiếp từ điển để các đối tượng, AutoMapper sẽ xếp hàng các phím với tên thuộc tính.

thông tin khác https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

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