Приведение с помощью GetType()

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

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


person Community    schedule 17.02.2009    source источник
comment
Мне любопытен ваш вариант использования здесь, так как тип переменной также не должен быть правильным, а динамическая типизация невозможна.   -  person Ray    schedule 17.02.2009
comment
Я предполагаю, что общий метод?   -  person lc.    schedule 17.02.2009
comment
Этот довольно старый. Первоначально я рассматривал реализацию языка Tutorial D на C# с использованием анонимных типов в качестве механизма хранения. Оказалось, что это плохая идея. dynamic мог бы это изменить, но с тех пор я отказался от проекта... пока.   -  person    schedule 07.02.2011


Ответы (5)


Ваше намерение очень неясно; однако один из вариантов — это дженерики и 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 с помощью дженериков, но мы по-прежнему мало что можем с ним сделать, кроме вызова других универсальных методов... что вы хотели здесь сделать?

person Marc Gravell    schedule 17.02.2009

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

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

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

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

person David Wengier    schedule 17.02.2009
comment
примечание: тип, возвращаемый GetSomeInput(), должен реализовывать IConvertible (сверху вниз). Я предполагаю, что это делают все встроенные типы .NET CLR. ;) - person EnocNRoll - AnandaGopal Pardue; 17.02.2009
comment
Я изменил ответы. Хотя convert полезен, он возвращает объект. Что мне действительно нужно, так это возврат фактического типа. - person ; 07.02.2011
comment
Вот допустимый вариант использования: из вызова сторонней библиотеки мы получаем имя метода, PropertyInfo и значение, которое всегда является двойным. Поскольку параметры некоторых методов являются целыми числами, наше приложение вылетало. С помощью этого кода мы можем без проблем преобразовать полученный двойник в ParameterInfo.ParameterType. Спасибо! :) - person Sergio Romero; 25.08.2011
comment
Вариант использования, который я сейчас использую: тип базового объекта, сохраненный в RavenDB, но мне нужен полный тип для механизма представления Razor в ASP.net MVC. Спасибо! - person Jason More; 04.02.2013
comment
Я нашел Convert.ChangeType(input, property.PropertyType); в соответствии с этим ответом: stackoverflow.com/questions/17703723/, которая мне нужна для аналогичной ситуации. - person Matt Kemp; 04.03.2015

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

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

person Spence    schedule 19.02.2009
comment
И как вы создаете экземпляры из типов, хранящихся в перечислении, без отражения? - person jayarjo; 21.08.2012
comment
Перечисления C# не хранят типы, конкретное перечисление является типом, и каждый экземпляр этого перечисления имеет значение. Если вы хотите использовать перечисление для создания типа, вам следует просто использовать фабрику и жестко запрограммировать ее для создания новых типов. - person Spence; 22.08.2012

У меня есть класс, который я использую для отслеживания изменений в моем Приложение 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;
        }
    }
}
person jp2code    schedule 18.06.2018
comment
Полное раскрытие информации: выше указано расширение StateGet, которое не включено. - person jp2code; 18.06.2018

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

myObj.getClass().cast(myObj)

person Luke Hill    schedule 13.02.2013