3

それらすべてに共通するいくつかのプロパティを持ついくつかのオブジェクトがあります。例えば:

オブジェクトAはタイプXで、​​10個のプロパティがあります

オブジェクトBはタイプYで、15個のプロパティがあります

オブジェクトCはタイプZで、7つのプロパティがあります

これらのオブジェクトはすべて、共通の「名前」、「署名」、および「チェックサム」プロパティを持っています。「name」、「signature」、「checksum」プロパティを含む任意のタイプのオブジェクトを受け入れることができる静的ヘルパーメソッドを作成しようとしています。それは可能ですか、それとも実際に3つの異なるメソッド(各タイプのオブジェクトを受け入れるための1つ)が必要ですか?

編集-その価値については、これらのオブジェクトがWebサービスを介して私に公開されていることについては言及しませんでした。

4

8 に答える 8

8

これらのプロパティを共通の基本クラスまたはインターフェイスに移動して使用する必要があります。

于 2011-12-14T19:19:10.603 に答える
4

2つの良い選択肢があります。1つ目は継承です。

public class CommonObject
{
    public string Name;
    public string Signature;
    public string Checksum;
}

public class X : CommonObject
{
    // other properties
}

public class Y : CommonObject
{
    // other properties
}

public class Z : CommonObject
{
    // other properties
}

public static void DoSomething(CommonObject o)
{
    // You can access these values
    if (o.Name == "" || o.Signature == "")
        o.Checksum = 0;
}

これらのプロパティを仮想化でき、各クラスをオーバーライドしてそれらを異なる方法で処理できるため、これは強力です。

2番目のオプションは、インターフェースを使用することです。

public class OtherClass
{
    public static void DoSomething(CommonObject o)
    {
        // code here
    }
}

public interface CommonObject
{
    string Name { get; }
    string Signature { get; }
    string Checksum { get; }
}

public class X : CommonObject
{
    private string _name = "";
    private string _signature = "";
    private string _checksum = "";

    string CommonObject.Name { get { return _name; } }
    string CommonObject.Signature { get { return _signature; } }
    string CommonObject.Checksum { get { return _checksum; } }
}
于 2011-12-14T19:28:52.713 に答える
2

可能です...共通のメソッドを含む共通のベースクラスを定義し、ベースのオブジェクトA、B、およびCのサブクラスを作成する場合。静的ヘルパーメソッドは、基本クラスをパラメータータイプとして使用でき、任意のサブタイプをメソッドに渡すことができます。

于 2011-12-14T19:19:21.947 に答える
2

インターフェースは私が信じるあなたの最良の選択肢です、

public interface ISomeGoodNameForCommonProperies 
{
  string Name {get;set;}
  string Signature {get;set;}
  string Checksum {get;set;}
}

public class X : ISomeGoodNameForCommonProperies 
{
  string Name {get;set;}
  string Signature {get;set;}
  string Checksum {get;set;}
  ...
}

public class Y : ISomeGoodNameForCommonProperies 
{
  string Name {get;set;}
  string Signature {get;set;}
  string Checksum {get;set;}
  ...
}

public class Z : ISomeGoodNameForCommonProperies 
{
  string Name {get;set;}
  string Signature {get;set;}
  string Checksum {get;set;}
  ...
}

その場合、ヘルパーメソッドはISomeGoodNameForCommonProperiesを取ります

public object MyHelperMethod(ISomeGoodNameForCommonProperies myObject)
{
  ...
}

継承はもちろん機能しますが、作成しようとしているオブジェクトにとって意味がない限り、基本クラスは避けます。あなたが自分自身に問うべき質問ですが、X、Y、Zはある種の異なるオブジェクトOとして定義できますか?もしそうなら、先に進んで、Oとそれに固有のものを作成してください。共通しているこれらの3つのプロパティでは論理エンティティを定義するのに十分ではないが、実用上の理由でグループ化する必要がある場合は、インターフェイスが最適なオプションです。

于 2011-12-14T19:25:48.120 に答える
2

別のオプションとして、動的型付けもあります。このオプションはあなたのために働くはずですが、私は間違いなく他の人が述べたようにインターフェースまたは基本クラスを使用しようとします。

于 2011-12-14T19:28:42.987 に答える
2

これらのオブジェクトはWebサービスを介して公開されるため、オブジェクトの定義を制御することはできないと想定します。それらはそれらが何であるかであり、共通の基本クラスまたはインターフェースからそれらを継承させることはできません。問題に対するその制約があるため、実際には2つの選択肢しかありません。

C#4.0以降を使用している場合は、新しい動的タイプを使用できます。これは基本的に、実行時までタイプの評価を行わないオブジェクト参照です。したがって、動的型で使用するプロパティまたはメソッドが存在しない場合、コンパイル中のエラーではなく、実行時エラーが発生します。

もう1つの方法は、Object型への参照を取得し、リフレクションを使用してプロパティとメソッドを操作することです。そこには醜い可能性がたくさんあります。

私はあなたがC#4+を使用していないので、私は3つの別々の方法で行くと思います。いくつかのコードを複製するかもしれませんが、c#3.5で使用する必要がある複雑で追跡が難しいリフレクション呼び出しの束よりもむしろそれを持っています-

于 2011-12-14T22:37:00.060 に答える
1

継承を使用できます。

于 2011-12-14T19:19:59.573 に答える
1

この問題には2つのアプローチがあります。

これらすべての共通のプロパティを持つ基本クラスを作成し、そこから他のプロパティを派生させます。

public abstract class MyBaseClass
{
    public string Name { get; set; }
    public string Signature { get; set; }
    public int Checksum { get; set; }
}

public class ClassX : MyBaseClass
{
    // Add the other properties here
}

public class ClassY : MyBaseClass
{
    // Add the other properties here
}

public class ClassZ : MyBaseClass
{
    // Add the other properties here
}

ヘルパーメソッドには、タイプMyBaseClassのパラメーターがあります。

public void MyHelperMethod(MyBaseClass obj)
{
    // Do something with obj.Name, obj.Siganture and obj.Checksum
}

ヘルパーメソッドをMyBaseClassに配置することもお勧めしますが、パラメーターなしで、プロパティに直接アクセスできるようになりました。

public abstract class MyBaseClass
{
    public string Name { get; set; }
    public string Signature { get; set; }
    public int Checksum { get; set; }

    public void CreateChecksum() // Your helper method
    {
        Checksum = Name.GetHashCode() ^ Signature.GetHashCode();
    }
}

次に、オブジェクトから直接呼び出すことができます。

objA.CreateChecksum();
objB.CreateChecksum();
objB.CreateChecksum();

または、3つのクラスが実装するインターフェースを定義します。

public interface IMyInterface
{
    string Name { get; set; }
    string Signature { get; set; }
    int Checksum { get; set; }
}

public class ClassX : IMyInterface
{
        public string Name { get; set; }
        public string Signature { get; set; }
        public int Checksum { get; set; }
    // Add the other properties here
}

public class ClassY : IMyInterface
{
        public string Name { get; set; }
        public string Signature { get; set; }
        public int Checksum { get; set; }
    // Add the other properties here
}

public class ClassZ : IMyInterface
{
        public string Name { get; set; }
        public string Signature { get; set; }
        public int Checksum { get; set; }
    // Add the other properties here
}

ヘルパーメソッドには、タイプIMyInterfaceのパラメーターがあります。

public void MyHelperMethod(IMyInterface obj)
{
    // Do something with obj.Name, obj.Siganture and obj.Checksum
}

このようにMyHelperMethodを呼び出すことができます

MyHelperMethod(objA);
MyHelperMethod(objB);
MyHelperMethod(objC);
于 2011-12-14T19:37:54.183 に答える