Nesne gerçek türüne nasıl dönüştürülür?


121

Sahip olursam:

void MyMethod(Object obj) {   ...   }

objGerçek türünün ne olduğunu nasıl belirleyebilirim ?


2
Tür, derleme zamanında biliniyor mu?
psubsee2003

1
Ve bundan ne elde etmeyi bekliyorsunuz? Lütfen bize nasıl başarmayı umduğunuzu değil, neyi başarmaya çalıştığınızı söyleyin.
Jon Skeet

@JonSkeet: Nesneden bir işlevi çağırabilmek istiyorum. obj.MyFunction();Gerçek nesnenin bu işleve sahip olduğunu bilmeme rağmen şu anda derleme yapmıyor.
Paul Lassiter

@ psubsee2003: hayır değil, çünkü birlikte çalışmayla iletilen bir nesne referansı.
Paul Lassiter

3
@PaulLassiter: Türü bilmiyorsanız, MyFunctionyöntemi ne bildirir ?
Jon Skeet

Yanıtlar:


194

Gerçek türü biliyorsanız, o zaman sadece:

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

Gerçek türü bilmiyorsanız, o zaman: gerçekten değil, hayır. Bunun yerine şunlardan birini kullanmanız gerekir:

  • yansıma
  • iyi bilinen bir arayüz uygulamak
  • dinamik

Örneğin:

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

1
Swift'deki eşdeğer sözdizimi nedir?
Nagendra Rao

1
Nevermind, astip yayınlama ve type(of: ClassName)örnek tipini kontrol etme işlevi için bulundu .
Nagendra Rao

43

Yapabileceğinizi sanmıyorum (derinlemesine düşünmeden değil), işlevinize de bir tür sağlamalısınız:

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

UPD :

Bu sizin için çalışabilir:

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

4
Bu gerçekten gereksiz bir cevap, artı oyu hak etmiyor. OP tarafından sorulduğu üzere, nesne türündeki bir nesnenin yansıması nesnenin "gerçek türünü" vermeyecektir. Ayrıca, MyMethod mantığınız kusurludur çünkü obj A tipinde olabilir ve B tipi de olabilir. Mantığınız "gerçek tip" sağlamaz (OP'nin istendiği gibi) - uyumlu bir tip sağlar ve zorunlu değildir o da istenen tip.
Jazimov

obj.GetType () kullanın. Bu kesinlikle gerçek tipini döndürecektir.
JSON

3

JsonConvert.DeserializeObject (object.ToString ()) nasıl olur;


Bu tatmin edici bir cevap değil. OP'nin sorusunun Json veya serileştirme ile ilgisi yoktur.

@ user12637955 bu aslında çalışan bir cevaptır, ancak kutulama ve kutudan çıkarma nedeniyle daha büyük karmaşıklığa sahiptir, yani nesne -> ToString () -> somut türe. Daha doğru olması için şu şekilde görünmelidir:var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
Kola

1

Benim durumumda AutoMapper iyi çalışıyor.

AutoMapper, herhangi bir açık yapılandırma olmadan dinamik nesnelere / nesnelere eşleme yapabilir:

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

Benzer şekilde, sözlüklerden nesnelere doğrudan eşleme yapabilirsiniz, AutoMapper anahtarları özellik adlarıyla hizalayacaktır.

daha fazla bilgi https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping


1

Bu yöntem en verimli olmayabilir, ancak basittir ve işi yapar.

İki işlem gerçekleştirir: ilk olarak temelde bir serileştirme olan .ToString () 'i çağırır ve ardından Newtonsoft nuget ( yüklemeniz gereken ) kullanarak seriyi kaldırma .

public T Format<T>(Object obj) =>
    JsonConvert.DeserializeObject<T>(obj.ToString());

Cevabınızı ilerideki okuyucular için kısaca açıklamalısınız.
Suraj Kumar

0

Senin Eğer MyFunction()yöntem bir sınıfın (ve onun soyundan) tek tanımlanır, denemek

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

Aramak istediğiniz işlevi tanımlayan ilgisiz sınıflarda çok sayıda varsa, bir arabirim tanımlamalı ve sınıflarınızın bu arabirimi tanımlamasını sağlamalısınız:

interface IMyInterface
{
    void MyFunction();
}

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

0

Şimdi türseniz, örneğin abc adlı sınıftan yönlendirilmişse, onu gerçek türüne çevirin. Fonksiyonunuzu şu şekilde çağırabilirsiniz:

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

İşlevi bilmiyorsanız, farklı bir şekilde yapılabilir. Her zaman kolay değil. Ama bir şekilde imzasıyla bulabilirsin. Sizin durumunuz buysa, bize bildirmelisiniz.


-1

Gerçek türe dönüştürmek kolaydır:

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

8
Bu mantıksız. Aslında gerçek türü bilmiyorsunuz. Bunu nasıl yapacaksın?
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 );
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.