9

同じインターフェースを持つ2つのクラスがあるとします。

interface ISomeInterface 
{
    int foo{get; set;}
    int bar{get; set;}
}

class SomeClass : ISomeInterface {}

class SomeOtherClass : ISomeInterface {}

SomeClassを表すISomeInterfaceのインスタンスがあるとします。各メンバーを手動でコピーせずに、それをSomeOtherClassの新しいインスタンスにコピーする簡単な方法はありますか?

更新: 記録のために、私はSomeClassのインスタンスをSomeOtherClassのインスタンスにキャストしようとはしていません。私がやりたいのは次のようなものです。

ISomeInterface sc = new SomeClass() as ISomeInterface;
SomeOtherClass soc = new SomeOtherClass();

soc.foo = sc.foo;
soc.bar = soc.bar;

これらのオブジェクトには多くのプロパティがあるため、手作業でこれを行う必要はありません。

4

9 に答える 9

9

各クラスに暗黙の演算子を作成して、変換を行うことができます。

public class SomeClass
{
    public static implicit operator SomeOtherClass(SomeClass sc)
    {
        //replace with whatever conversion logic is necessary
        return new SomeOtherClass()
        {
            foo = sc.foo,
            bar = sc.bar
        }
    }

    public static implicit operator SomeClass(SomeOtherClass soc)
    {
        return new SomeClass()
        {
            foo = soc.foo,
            bar = soc.bar
        }
    }
    //rest of class here
}

その後SomeOtherClass soc = sc;、その逆も機能します。

于 2008-11-19T22:27:59.053 に答える
6

それをする必要がないというインターフェースのポイントではありませんか?SomeOtherClassの具体的な実装で何かをしていますか?具体的な実装を使用する代わりに、インターフェースを使用してください。SomeClassクラスとSomeOtherクラスのどちらを使用するかは問題ではありません。

それ以外にできる最善の方法は、次のようにインターフェイス上の各プロパティをコピーする、ある種のヘルパー関数を作成することです(手動で行うか、リフレクションを調べる必要があります)。

   public ISomeInterface CopyValues(ISomeInterface fromSomeClass, ISomeInterface toSomeOtherClass)
   {
    //copy properties here
    return toSomeOtherClass;
    }

ただし、私の最初の本能は、実装から離れて、代わりにインターフェイスを使用して集中することです。そうすれば、その下に何があるかは問題になりません。

于 2008-11-19T22:12:04.000 に答える
4

リフレクション...すべてのプロパティをループし、他のオブジェクトの対応するプロパティに設定します。

于 2008-11-19T22:08:44.490 に答える
4

Reflection ソリューションに関する Joe の回答をご覧ください。

Visual Studio を使用していると仮定します。

ctrl+shift+r および ctrl+shift+p ショートカットに慣れていますか? そうでない場合は、ctrl+shift+r でキーストローク マクロの記録を開始/終了します。ctrl+shift+p は、記録されたマクロを再生します。

多くのプロパティを設定したときに行ったことは、プロパティ宣言を設定したい場所にコピーし、宣言を set ステートメントに変更してカーソルを次の行に移動するためのマクロを記録することです。すべての設定ステートメントが完了するまで再生してください。

于 2008-11-19T23:31:37.397 に答える
3

いいえ、オブジェクトをあるタイプから別のタイプに透過的に変換(キャスト)するには、オブジェクトの基になる具象クラスは、両方が同じインターフェイスを実装している場合でも、キャストしようとしているクラスから継承する必要があります。

考えてみてください。同じインターフェースを実装するには、2つのオブジェクトすべてが共通していて、メソッドシグネチャの同じサブセットである必要があります。それらは同じプロパティまたはデータフィールドを持っていない可能性があります(おそらくそうではありません)。

于 2008-11-19T22:10:19.760 に答える
3

これはうまくいきませんか?

class MyClass : ICloneable
{
public MyClass()
{

}
public object Clone() // ICloneable implementation
{
MyClass mc = this.MemberwiseClone() as MyClass;

return mc;
}

MyClass.Clone()を呼び出すだけです。

于 2008-11-19T22:13:07.650 に答える
3
   ISomeInterface sc = new SomeClass() as ISomeInterface;
   SomeOtherClass soc = new SomeOtherClass();
   foreach (PropertyInfo info in typeof(ISomeInterface)
                                     .GetProperties(BindingFlags.Instance
                                                     |BindingFlags.Public))
   {
       info.SetValue(soc,info.GetValue(sc,null),null);
   }
于 2008-11-19T23:53:29.443 に答える
3

「それを行う方法の例を教えていただけますか (または、少なくとも使用する適切な方法を教えてください)? MSDN でそれらを見つけることができないようです」 – ジェイソン・ベイカー

ジェイソン、次のようなもの:

var props = typeof(Foo)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo p in props)
{
     // p.Name gives name of property
}

実行時にリフレクティブに実行するのではなく、コピー コンストラクターに必要なコードを吐き出すツールを作成することをお勧めします。これはパフォーマンスが低下します。

于 2008-11-19T23:10:41.917 に答える
2

私は次のようにしましたが、暗黙の演算子を使用してあるオブジェクトから別のオブジェクトに変換するのは非常にうまく機能します:

クラス プログラム
    {
        static void Main(string[] args)
        {
            Console.WriteLine("こんにちは");
            ExecutionReport er = new ExecutionReport("ORDID1234",3000.43,DateTime.UtcNow);
            Order ord = new Order();
            順序 = えー;
            Console.WriteLine("転送される値: " + er.OrderId + "\t" + ord.Amount.ToString() + "\t" + ord.TimeStamp.ToString() + "\t");
            Console.ReadLine();
        }
    }


    public クラスの順序
    {
        パブリック文字列 OrderId { get; 設定; }
        public double 金額 { get; 設定; }
        public DateTime TimeStamp { get; 設定; }
        public static implicit operator ExecutionReport(Order ord)
        {
            新しい ExecutionReport() を返す
            {
                OrderId = ord.OrderId,
                金額 = ord.Amount,
                タイムスタンプ = ord.TimeStamp
            };
        }
        public static implicit operator Order(ExecutionReport er)
        {
            new Order() を返す
            {
                OrderId = er.OrderId、
                量 = er.量、
                タイムスタンプ = er.TimeStamp
            };
        }

        治安()
        { }
    }

    パブリック クラス ExecutionReport
    {
        パブリック文字列 OrderId { get; 設定; }
        public double 金額 { get; 設定; }
        public DateTime TimeStamp { get; 設定; }
        public ExecutionReport() { }
        public ExecutionReport(string orderId,double amount, DateTime ts)
        {
            OrderId = orderId; 金額 = 金額; タイムスタンプ = ts;
        }
    }
于 2010-12-08T20:56:14.737 に答える