147 votes

Comment transformer un objet en son type réel ?

Si je l'ai fait :

void MyMethod(Object obj) {   ...   }

Comment puis-je lancer obj à ce que son type réel est ?

226voto

Marc Gravell Points 482669

Si vous connaissez le type réel, alors juste :

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

Si vous ne connaissez pas le type réel, alors : pas vraiment, non. Vous devriez plutôt utiliser l'un des éléments suivants :

  • réflexion
  • la mise en œuvre d'une interface bien connue
  • dynamique

Par exemple :

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

48voto

Maksim Vi. Points 3313

Je ne pense pas que vous puissiez le faire (pas sans réflexion), vous devriez également fournir un type à votre fonction :

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

UPD :

Cela peut fonctionner pour vous :

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

4voto

albin Points 11

Et si

JsonConvert.DeserializeObject<SomeType>(object.ToString());

1voto

devio Points 22981

Si votre MyFunction() n'est définie que dans une seule classe (et ses descendantes), essayez

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

Si vous avez un grand nombre de classes non liées définissant la fonction que vous voulez appeler, vous devez définir une interface et faire en sorte que vos classes définissent cette interface :

interface IMyInterface
{
    void MyFunction();
}

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

1voto

Soren Points 684

Dans mon cas, AutoMapper fonctionne bien.

AutoMapper peut établir des correspondances vers/depuis des objets dynamiques sans aucune configuration explicite :

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

De même, vous pouvez faire correspondre directement des dictionnaires à des objets, AutoMapper alignera les clés avec les noms des propriétés.

plus d'infos https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X