Nếu tôi có:
void MyMethod(Object obj) { ... }
Làm cách nào để tôi có thể truyền obj
đến loại thực tế của nó?
obj.MyFunction();
không biên dịch, mặc dù tôi biết rằng đối tượng thực có chức năng đó.
MyFunction
phương thức?
Nếu tôi có:
void MyMethod(Object obj) { ... }
Làm cách nào để tôi có thể truyền obj
đến loại thực tế của nó?
obj.MyFunction();
không biên dịch, mặc dù tôi biết rằng đối tượng thực có chức năng đó.
MyFunction
phương thức?
Câu trả lời:
Nếu bạn biết loại thực tế, thì chỉ cần:
SomeType typed = (SomeType)obj;
typed.MyFunction();
Nếu bạn không biết loại thực tế, thì: không hẳn, không. Thay vào đó, bạn sẽ phải sử dụng một trong số:
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();
as
để đánh máy và type(of: ClassName)
chức năng để kiểm tra kiểu phiên bản.
Tôi không nghĩ rằng bạn có thể (không phải không có 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);
...
}
CẬP NHẬT :
Đ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;
...
}
}
Làm thế nào về JsonConvert.DeserializeObject (object.ToString ());
var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
Trong trường hợp của tôi, AutoMapper hoạt động tốt.
AutoMapper có thể ánh xạ đến / từ các đối tượng động mà không cần bất kỳ cấu hình rõ ràng nào:
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ạ thẳng từ từ điển sang các đối tượng, AutoMapper sẽ sắp xếp các phím với tên thuộc tính.
thêm thông tin https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping
Phương pháp này có thể không hiệu quả nhất nhưng đơn giản và hiệu quả.
Nó thực hiện hai hoạt động: đầu tiên nó gọi .ToString () về cơ bản là tuần tự hóa, và sau đó là giải mã hóa bằng Newtonsoft nuget (mà bạn phải cài đặt).
public T Format<T>(Object obj) =>
JsonConvert.DeserializeObject<T>(obj.ToString());
Nếu MyFunction()
phương thức của bạn chỉ được xác định trong một lớp (và các lớp con 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 các lớp không liên quan xác định hàm bạn muốn gọi, bạn nên xác định một giao diện và làm cho các lớp của bạn xác định giao diện đó:
interface IMyInterface
{
void MyFunction();
}
void MyMethod(Object obj)
{
var o = obj as IMyInterface;
if (o != null)
o.MyFunction();
}
Truyền nó sang kiểu thực của nó nếu bây giờ bạn là kiểu, chẳng hạn như kiểu nó được định hướng từ lớp có tên abc. Bạn có thể gọi hàm của mình theo cách này:
(abc)(obj)).MyFunction();
nếu bạn không biết chức năng, nó có thể được thực hiện theo một cách khác. Không dễ dàng luôn luôn. 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.
Truyền sang loại thực tế rất dễ dàng:
void MyMethod(Object obj) {
ActualType actualyType = (ActualType)obj;
}
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 );
}