web-dev-qa-db-ja.com

GetType()でキャストする

GetType()から返されたタイプにオブジェクトをキャストすることは可能ですか? (匿名型の)オブジェクトを受け入れ、匿名型としてキャストされたオブジェクトを返すことができるジェネリックメソッドが欲しいのですが。 LCG DynamicMethodを使用してコンテナークラスのメソッドを構築することを考えていましたが、それがどのように見えるかを正確に理解できません。 GetType()メソッドを使用してキャストするアイデアは、匿名の型を取得し、実際に型を知らなくてもオブジェクトをその実際の型にキャストできるようにすることでした。

包括的な目標は、匿名型のオブジェクトをコンテナに貼り付けることです。これにより、メソッド間で共有したり渡したりすることができます。

30
user29439

あなたの意図は非常に不明確です。ただし、1つのオプションはジェネリック、特に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と入力された値が得られました。ただし、otherジェネリックメソッドを呼び出す以外は、これを使用してできることはまだ多くありません...ここでしたいですか?

15
Marc Gravell

とにかくコンパイル時に型を知らないと、結果を使用して役立つことは何もできないので、GetType()としてキャストする理由を考えることができません。

おそらくあなたが探しているのは、変換できることです。その場合は、次のようにしてください。

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

すべて文字列として格納されているレジストリから値を読み取り、リフレクションを使用してプロパティに詰め込むときに、これを使用します。

39
David Wengier

Activator.CreateInstanceメソッドを使用して、型からインスタンスを作成します。

FYIリフレクションはSLOOWWWWであるため、連続してこのキャストを何度も行う必要がある場合は、列挙型などの型を定義してから、リフレクションを使用せずにインスタンスを作成することをお勧めします。

4
Spence

すべてのアイテムが databound でなかったため、 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
jp2code