user29439
user29439

Reputation:

Cast with GetType()

Is it possible to cast an object to the type returned from GetType()? I'd like a generic method that can accept an object (for anonymous types) but then return an object cast as the anonymous type. I've been thinking of using the LCG DynamicMethod to build a method on a container class, but I can't exactly figure out what that would look like. The idea to cast with the GetType() method was to be able to get the anonymous type and cast an object to its actual type without actually knowing the type.

The overarching goal is to stick anonymous-typed objects into a container, that I could then share and pass between methods.

Upvotes: 49

Views: 68162

Answers (5)

user153923
user153923

Reputation:

I have a class that I use for change tracking in my Windows Forms app because not all items were databound. Most items were TextBox controls, but there were ComboBox and DateTimePicker controls as well.

For simplicity, my HasChanged property tests the generic Windows.Forms.Control to see if it is a ComboBox, but you could test whatever types of controls you add to your Windows Form.

Below is that class - if it helps for anyone.

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

Upvotes: 0

Luke Hill
Luke Hill

Reputation: 1

You can use getClass() which returns a Class object then use the cast method in the Class object to cast the object to an object of that Class's type, like so:

myObj.getClass().cast(myObj)

Upvotes: -3

Spence
Spence

Reputation: 29332

You can use the Activator.CreateInstance method to create an instance from a type.

FYI reflection is SLOOWWWW, so if you need to do this cast many times in a row, it may be better to define your types in an enum or something like this then create instances without using reflection.

Upvotes: 3

David Wengier
David Wengier

Reputation: 10179

I can't think of why you'd want to cast as GetType(), because you wouldn't be able to do anything to useful with the result, without knowing the type at compile time anyway.

Perhaps what you are looking for, is being able to Convert. If that is the case, the following should work for you:

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

We use this when reading values from the registry which are all stored as strings, and then stuffing them into properties using reflection.

Upvotes: 52

Marc Gravell
Marc Gravell

Reputation: 1062780

Your intent is very unclear; however, one option is generics and MakeGenericMethod in particular. What do you want to do with this? For example:

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?
    }    
}

So now we have the value, typed as double via generics - but there still isn't much we can do with it except for calling other generic methods... what was it you want to do here?

Upvotes: 20

Related Questions