web-dev-qa-db-fra.com

Cast avec GetType ()

Est-il possible de convertir un objet dans le type renvoyé par GetType()? Je souhaiterais une méthode générique pouvant accepter un objet (pour les types anonymes), mais renvoyer ensuite un transtypage d'objet en tant que type anonyme. J'ai envisagé d'utiliser LCG DynamicMethod pour créer une méthode sur une classe conteneur, mais je ne peux pas comprendre exactement à quoi elle ressemblerait. L'idée de transtyper avec la méthode GetType() était de pouvoir obtenir le type anonyme et de transtyper un objet sur son type actuel sans connaître réellement le type.

L'objectif principal est de coller des objets de type anonyme dans un conteneur, que je pourrais ensuite partager et transmettre entre les méthodes.

27
user29439

Votre intention n'est pas très claire. Cependant, une option est générique 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?
    }    
}

Nous avons donc maintenant la valeur, tapée double via des génériques - mais nous ne pouvons pas grand chose à faire avec elle sauf en appelant autre méthodes génériques ... que vouliez-vous faire ici?

13
Marc Gravell

Je ne vois pas pourquoi vous voudriez utiliser GetType (), car vous ne pourriez rien faire d’utile avec le résultat, sans connaître le type au moment de la compilation.

Peut-être que ce que vous cherchez, c'est pouvoir vous 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 stockées sous forme de chaînes, puis de leur insertion dans des propriétés à l'aide de la réflexion.

38
David Wengier

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

La réflexion de FYI est SLOOWWWW, donc si vous devez effectuer cette conversion plusieurs fois de suite, il peut être préférable de définir vos types dans une énumération ou quelque chose comme cela, puis de créer des instances sans utiliser de réflexion.

4
Spence

J'ai une classe que j'utilise pour le suivi des modifications dans mon Windows Forms app car tous les éléments étaient databound . La plupart des éléments étaient des commandes TextBox , mais il existait également des commandes ComboBox et DateTimePicker .

Par souci de simplicité, ma propriété HasChanged teste le fichier générique Windows.Forms.Control pour voir s’il s’agit d’un ComboBox , mais vous pouvez tester tous les types de contrôles ajoutés à votre Windows Form.

Ci-dessous se trouve cette classe - si cela peut aider 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
jp2code