Bagaimana cara mentransmisikan Object ke tipe aslinya?

121

Jika saya memiliki:

void MyMethod(Object obj) {   ...   }

Bagaimana cara mentransmisikan objke tipe sebenarnya?

Paul Lassiter
sumber
2
Apakah tipe tersebut diketahui pada waktu kompilasi?
psubsee2003
1
Dan apa yang ingin Anda capai dari ini? Tolong beri tahu kami apa yang Anda coba capai, bukan bagaimana Anda berharap untuk mencapainya.
Jon Skeet
@JonSkeet: Saya ingin dapat memanggil fungsi dari objek. Saat obj.MyFunction();ini tidak dapat dikompilasi, meskipun saya tahu bahwa objek sebenarnya memiliki fungsi itu.
Paul Lassiter
@ psubsee2003: tidak, karena ini adalah referensi objek yang dilewatkan melalui interop.
Paul Lassiter
3
@PaulLassiter: Jika Anda tidak tahu tipenya, apa yang mendeklarasikan MyFunctionmetodenya?
Jon Skeet

Jawaban:

194

Jika Anda tahu tipe sebenarnya, maka:

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

Jika Anda tidak tahu tipe sebenarnya, maka: tidak juga, tidak. Anda harus menggunakan salah satu dari:

  • refleksi
  • menerapkan antarmuka terkenal
  • dinamis

Sebagai contoh:

// 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();
Marc Gravell
sumber
1
Apa sintaks yang setara di Swift?
Nagendra Rao
1
Nevermind, ditemukan asuntuk typecasting dan type(of: ClassName)fungsi untuk memeriksa jenis instance.
Nagendra Rao
43

Saya rasa Anda tidak bisa (bukan tanpa refleksi), Anda harus memberikan tipe untuk fungsi Anda juga:

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

UPD :

Ini mungkin berhasil untuk Anda:

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}
Maksim Vi.
sumber
4
Ini benar-benar jawaban yang tidak berguna, tidak layak mendapat suara positif. Refleksi dari sebuah objek bertipe objek tidak akan menghasilkan “tipe sebenarnya” dari objek tersebut, seperti yang diminta oleh OP. Selain itu, logika MyMethod Anda cacat karena obj bisa dari tipe A dan juga bisa dari tipe B. Logika Anda tidak menyediakan "tipe sebenarnya" (seperti yang diminta OP) - ini menyediakan tipe yang kompatibel, dan belum tentu jenis yang diinginkan saat itu.
Jazimov
gunakan obj.GetType (). Itu pasti akan mengembalikan tipe aslinya.
JSON
3

Bagaimana dengan JsonConvert.DeserializeObject (object.ToString ());

albin
sumber
Ini bukanlah jawaban yang memuaskan. Pertanyaan OP tidak ada hubungannya dengan Json atau serialisasi.
@ user12637955 ini sebenarnya adalah jawaban yang berfungsi, tetapi memiliki kompleksitas yang lebih besar, karena tinju dan unboxing, yaitu objek -> ToString () -> ke tipe konkret. Untuk lebih akuratnya akan terlihat seperti ini:var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
Coke
1

Dalam kasus saya, AutoMapper berfungsi dengan baik.

AutoMapper dapat memetakan ke / dari objek dinamis tanpa konfigurasi eksplisit apa pun:

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);

Demikian pula Anda dapat memetakan langsung dari kamus ke objek, AutoMapper akan membariskan kunci dengan nama properti.

info lebih lanjut https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

Soren
sumber
1

Metode ini mungkin bukan yang paling efisien tetapi sederhana dan berhasil.

Ini melakukan dua operasi: pertama memanggil .ToString () yang pada dasarnya adalah serialisasi, dan kemudian deserialisasi menggunakan Newtonsoft nuget (yang harus Anda instal).

public T Format<T>(Object obj) =>
    JsonConvert.DeserializeObject<T>(obj.ToString());
bombek
sumber
Anda harus menjelaskan jawaban Anda secara singkat untuk pembaca yang akan datang.
Suraj Kumar
0

Jika MyFunction()metode Anda hanya ditentukan dalam satu kelas (dan turunannya), coba

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

Jika Anda memiliki jumlah besar di kelas yang tidak terkait yang mendefinisikan fungsi yang ingin Anda panggil, Anda harus menentukan antarmuka dan membuat kelas Anda menentukan antarmuka itu:

interface IMyInterface
{
    void MyFunction();
}

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

Transmisikan ke tipe aslinya jika Anda sekarang tipe, misalnya berorientasi dari kelas bernama abc. Anda dapat memanggil fungsi Anda dengan cara ini:

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

jika Anda tidak tahu fungsinya, itu bisa dilakukan dengan cara yang berbeda. Tidak selalu mudah. Tetapi Anda dapat menemukannya dengan beberapa cara melalui tanda tangannya. Jika ini kasus Anda, beri tahu kami.

Masoud
sumber
-1

Mentransmisi ke tipe sebenarnya itu mudah:

void MyMethod(Object obj) {
    ActualType actualyType = (ActualType)obj;
}
pengguna1610694
sumber
8
Ini tidak masuk akal. Anda sebenarnya tidak tahu tipe sebenarnya. Bagaimana Anda bisa melakukan itu?
Allen Linatoc
-2
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 );
}
Hassan Boutougha
sumber