Приведение с помощью GetType () - PullRequest
28 голосов
/ 17 февраля 2009

Возможно ли привести объект к типу, возвращенному из GetType()? Я хотел бы универсальный метод, который может принять объект (для анонимных типов), но затем вернуть объект, приведенный как анонимный тип. Я думал об использовании LCG DynamicMethod для создания метода в классе контейнера, но я не могу точно понять, как это будет выглядеть. Идея приведения с помощью метода GetType() состояла в том, чтобы иметь возможность получить анонимный тип и привести объект к его фактическому типу без фактического знания типа.

Всеобъемлющая цель - поместить объекты анонимного типа в контейнер, который я затем мог бы разделить и передать между методами.

Ответы [ 5 ]

39 голосов
/ 17 февраля 2009

Я не могу понять, почему вы захотите привести его как GetType (), потому что вы не сможете сделать что-нибудь полезное с результатом, не зная тип во время компиляции.

Возможно, то, что вы ищете, это возможность конвертировать. Если это так, у вас должно работать следующее:

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

Мы используем это при чтении значений из реестра, которые все хранятся в виде строк, и затем вставке их в свойства с помощью отражения.

15 голосов
/ 17 февраля 2009

Ваше намерение очень неясно; тем не менее, один из вариантов - это дженерики и MakeGenericMethod в частности. Что вы хотите сделать с этим? Например:

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

Итак, теперь у нас есть значение, типизированное как double с помощью обобщений - но мы все еще мало что можем с ним сделать, за исключением вызова других обобщенных методов ... что вы хотели здесь делать?

4 голосов
/ 19 февраля 2009

Вы можете использовать метод Activator.CreateInstance для создания экземпляра из типа.

FYI-отражение - SLOOWWWW, поэтому, если вам нужно выполнять это приведение много раз подряд, может быть лучше определить ваши типы в перечислении или чем-то подобном, а затем создавать экземпляры без использования отражения.

0 голосов
/ 18 июня 2018

У меня есть класс, который я использую для отслеживания изменений в моем приложении Windows Forms , поскольку не все элементы были привязаны данными . Большинство элементов были TextBox , но также были элементы управления ComboBox и DateTimePicker .

Для простоты мое свойство HasChanged проверяет универсальный Windows.Forms.Control , чтобы определить, является ли он ComboBox , но вы можете проверить любые типы элементов управления, которые вы добавляете Ваша форма Windows.

Ниже приведен этот класс - если он кому-нибудь поможет.

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 голосов
/ 14 февраля 2013

Вы можете использовать getClass (), который возвращает объект Class, а затем использовать метод cast в объекте Class, чтобы привести объект к объекту этого класса, например:

myObj.getClass (). Литая (myObj)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...