6

私は現在、このタイプのコードを持っています:

private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    if (MainObject is SomeClassType1)
    {
        SomeClassType1 HelpObject = (SomeClassType1)MainObject;
        HelpObject.Property1 = Arg1;
        HelpObject.Property2 = Arg2;
    }
    else if (MainObject is SomeClassType2)
    {
        SomeClassType2 HelpObject = (SomeClassType2)MainObject;
        HelpObject.Property1 = Arg1;
        HelpObject.Property2 = Arg2;
    }
}

SomeClassType1 と SomeClassType2 に割り当てたい同じプロパティ セットがあると仮定すると (他のプロパティでは異なる場合があります)、MainObject を適切な型に動的にキャストし、コードを複製せずに値を割り当てることは可能ですか? これは私が最後に見たいものです:

private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    Type DynamicType = null;

    if (MainObject is SomeClassType1)
    {
        DynamicType = typeof(SomeClassType1);
    }
    else if (MainObject is SomeClassType2)
    {
        DynamicType = typeof(SomeClassType2);
    }

    DynamicType HelpObject = (DynamicType)MainObject;
    HelpObject.Property1 = Arg1;
    HelpObject.Property2 = Arg2;
}

そして明らかに、C# は DynamicType を見つけることができないと不平を言っています:

型または名前空間名 'DynamicType' が見つかりませんでした (using ディレクティブまたはアセンブリ参照がありませんか?)

このようなことは C# 2.0 で可能ですか? 現在のコードよりも厄介な場合は、これを行う意味がないと思いますが、調べることに非常に興味があります。ありがとう!

編集:明確にするために、インターフェースを実装することが最も適切で、おそらく正しい解決策であることを完全に理解しています。とはいえ、インターフェースを実装せずにそれを行う方法を知りたいと思っています。素晴らしい返信をありがとう!

4

7 に答える 7

15

気になるタイプは両方とも、同じ 2 つのプロパティを実装しているようです。その場合、これらのプロパティのインターフェイスを定義する必要があります。

public interface IMyInterface
{
   public Foo Property1 {get; set;}
   public Bar Property2 {get;set;}
}

次に、各クラスがその新しいインターフェイスを実装することをコンパイラに伝えるようにします。最後に、そのインターフェイスに制約される型引数を持つジェネリック メソッドを使用します。

private void FillObject<T>(T MainObject, Foo Arg1, Bar Arg2) 
    where T : IMyInterface
{
    MainObject.Property1 = Arg1;
    MainObject.Property2 = Arg2;
}

インターフェイスを宣言するための追加のコードを使用しても、これらのスニペットは、質問に投稿したスニペットのいずれよりも短くなり、関心のあるタイプの数が増えた場合、このコードを拡張するのがはるかに簡単になることに注意してください。

于 2009-02-19T18:23:40.823 に答える
9

基本的に、ここで行っていることは、オブジェクトの型に基づいて switch ステートメントを作成することです。最初の例以外にこれを行うための本質的に良い方法はありません(せいぜい退屈です)。

型を切り替えるための小さなフレームワークを作成して、構文をもう少し簡潔にしました。以下のようなコードを書くことができます。

TypeSwitch.Do(
    sender,
    TypeSwitch.Case<Button>(
        () => textBox1.Text = "Hit a Button"),
    TypeSwitch.Case<CheckBox>(
        x => textBox1.Text = "Checkbox is " + x.Checked),
    TypeSwitch.Default(
        () => textBox1.Text = "Not sure what is hovered over"));

ブログ投稿: http://blogs.msdn.com/jaredpar/archive/2008/05/16/switching-on-types.aspx

于 2009-02-19T18:21:16.113 に答える
7

SomeClassType1、SomeClassType2 などを変更できますか? はいの場合は、共通のプロパティを含むインターフェイスを作成し、その中でこのインターフェイスに型キャストしFillObject()てプロパティを設定することをお勧めします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SO566510
{
    interface IMyProperties
    {
        int Property1 { get; set; }
        int Property2 { get; set; }
    }

    class SomeClassType1 : IMyProperties
    {
        public int Property1 { get; set; }
        public int Property2 { get; set; }
    }

    class SomeClassType2 : IMyProperties
    {
        public int Property1 { get; set; }
        public int Property2 { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var obj1 = new SomeClassType1();
            var obj2 = new SomeClassType2();

            FillObject(obj1, 10, 20);
            FillObject(obj2, 30, 40);

        }

        private static void FillObject(IMyProperties objWithMyProperties
                                   , int arg1, int arg2)
        {
            objWithMyProperties.Property1 = arg1;
            objWithMyProperties.Property2 = arg2;
        }
    }
}
于 2009-02-19T18:22:45.270 に答える
4
private void FillObject(Object MainObject, Foo Arg1, Bar Arg2)
{
    Type t = MainObject.GetType();

    t.GetProperty("Property1").SetValue(MainObject, Arg1, null);
    t.GetProperty("Property2").SetValue(MainObject, Arg2, null);
}
于 2009-02-19T18:22:31.977 に答える
3

いくつかのアイデア:

  1. 共通のプロパティを持つ同じタイプから両方のタイプを継承させる
  2. 両方の型で、共通のプロパティを持つ同じインターフェイスを実装する
  3. プロパティを直接設定するのではなく、リフレクションを使用してプロパティを設定します (これはおそらく価値があるというよりも醜いです)。
  4. 新しい動的機能を使用してください。これは試していませんが、問題に対処できるようです
于 2009-02-19T18:24:10.917 に答える
2

キャストする代わりに、リフレクションを使用してプロパティを設定してみてください。

于 2009-02-19T18:21:20.857 に答える
0

ASP.NET MVC アプリでリフレクションを使用してオブジェクトを動的にキャストしています。基本的に、クラスのプロパティを列挙し、データ ストアで対応する値を見つけ、その値を動的にキャストしてオブジェクト インスタンスに割り当てます。私のブログ記事「 .NET を使用した動的キャスト」を参照してください。

于 2010-03-31T20:35:41.427 に答える