Cast avec GetType()

Est-il possible de convertir un objet au type renvoyé par GetType()? Je voudrais une méthode générique qui peut accepter un objet (pour les types anonymes) mais ensuite renvoyer un objet jeté comme type anonyme. J'ai pensé à utiliser le LCG DynamicMethod pour construire une méthode sur une classe de conteneur, mais je ne peux pas exactement comprendre à quoi cela ressemblerait. L'idée de lancer avec la méthode GetType() était de pouvoir obtenir le type anonyme et lancer un objet à son type réel sans réellement connaître le type.

L'objectif global est de coller des objets typés anonymes dans un conteneur, que je pourrais ensuite partager et passer entre les méthodes.

27
demandé sur bluish 2009-02-17 06:42:41

5 réponses

Votre intention est très peu claire; cependant, une option est les génériques et MakeGenericMethod en particulier. Que voulez-vous faire avec ça? Par exemple:

static class Program
{
    static void Main()
    {
        object obj = 123.45;
        typeof(Program).GetMethod("DoSomething")
            .MakeGenericMethod(obj.GetType())
            .Invoke(null, new object[] { obj });
    }
    public static void DoSomething<T>(T value)
    {
        T item = value; // well... now what?
    }    
}

Donc maintenant nous avons la valeur, tapée comme double via des génériques-mais il n'y a toujours pas grand-chose que nous pouvons faire avec, sauf pour appeler Autres méthodes génériques... qu'était-ce que vous voulez faire ici?

13
répondu Marc Gravell 2009-02-17 04:52:57

Je ne peux pas penser à pourquoi vous voudriez lancer comme GetType(), parce que vous ne seriez pas capable de faire quelque chose d'utile avec le résultat, sans connaître le type au moment de la compilation de toute façon.

Peut-être que ce que vous cherchez, c'est être capable de convertir. Si tel est le cas, ce qui suit devrait fonctionner pour vous:

object input = GetSomeInput();
object result = Convert.ChangeType(input, someOtherObject.GetType());

Nous l'utilisons lors de la lecture de valeurs du Registre qui sont toutes stockées sous forme de chaînes, puis les bourrer dans des propriétés en utilisant la réflexion.

36
répondu David Wengier 2009-02-17 05:32:19

Vous pouvez utiliser la méthode Activator.CreateInstance pour créer une instance à partir d'un type.

FYI reflection est SLOOWWWW, donc si vous avez besoin de faire ce cast plusieurs fois de suite, il peut être préférable de définir vos types dans une énumération ou quelque chose comme ça, puis créer des instances sans utiliser de réflexion.

4
répondu Spence 2009-02-19 02:35:01

J'ai une classe que j'utilise pour le suivi des modifications dans mon Windows Forms application, car pas tous les éléments ont été databound. La plupart des éléments étaient des contrôles TextBox , mais il y avait aussi des contrôlesComboBox etDateTimePicker .

Pour simplifier, ma propriété HasChanged teste les fenêtres génériques .Forme.Control pour voir s'il s'agit d'une ComboBox, mais vous pouvez tester les types de contrôles que vous ajoutez à votre formulaire Windows.

Ci-dessous est que classe - si cela aide pour n'importe qui.

internal class DataItem
{
    private static Color originalBackColor, changedBackColor, originalForeColor, changedForeColor;
    private static Font originalFont, changedFont;

    static DataItem()
    {
        originalBackColor = SystemColors.Control;
        changedBackColor = SystemColors.HighlightText;
        originalForeColor = Color.Black;
        changedForeColor = Color.Red;
        originalFont = new Font(FontFamily.GenericSansSerif, 12.5f);
        changedFont = new Font(originalFont, FontStyle.Bold);
    }

    public static void ChangeSetup(Control original, Color changedBackgroundColor)
    {
        originalBackColor = original.BackColor;
        originalForeColor = original.ForeColor;
        originalFont = original.Font;
        changedBackColor = changedBackgroundColor;
        changedFont = new Font(originalFont, FontStyle.Bold);
    }

    private bool changeTracking;

    public DataItem(Control control, Object value)
    {
        this.Control = control;
        var current = String.Format("{0}", Control.Text).Trim();
        if (Control is ComboBox)
        {
            var cbo = (ComboBox)Control;
            current = cbo.StateGet();
        }
        this.OriginalValue = current;
        this.Control.TextChanged += Control_TextChanged;
        changeTracking = true;
    }

    public Control Control { get; private set; }

    private void Control_TextChanged(Object sender, EventArgs e)
    {
        if (TrackingChanges)
        {
            if (HasChanged)
            {
                this.Control.BackColor = originalBackColor;
                this.Control.Font = originalFont;
                this.Control.ForeColor = originalForeColor;
            }
            else
            {
                this.Control.BackColor = changedBackColor;
                this.Control.Font = changedFont;
                this.Control.ForeColor = changedForeColor;
            }
        }
    }

    public bool HasChanged
    {
        get
        {
            var current = String.Format("{0}", Control.Text).Trim();
            if (Control is ComboBox)
            {
                var cbo = (ComboBox)Control;
                current = cbo.StateGet();
            }
            return !current.Equals(OriginalValue);
        }
    }

    public String OriginalValue { get; private set; }

    public void Reset()
    {
        changeTracking = false;
        this.OriginalValue = String.Empty;
        this.Control.Text = String.Empty;
        this.Control.BackColor = originalBackColor;
        this.Control.Font = originalFont;
        this.Control.ForeColor = originalForeColor;
    }
    public bool TrackingChanges
    {
        get
        {
            return changeTracking;
        }
    }
}
0
répondu jp2code 2018-06-18 15:40:37

Vous pouvez utiliser getClass() qui renvoie un objet de classe puis utiliser la méthode cast dans L'objet de classe pour convertir l'objet en un objet du type de cette classe, comme ceci:

MyObj.getClass ().cast (myObj)

-3
répondu Luke Hill 2013-02-13 23:03:02