1

Person基本クラスと 3 つの派生クラスがあります。編集ページには、一般的な個人データ (名前、住所など) を含むセクションがあります。

また、サブクラスごとにセクションが必要です。したがって、aPersonが a の場合User、特定のユーザー データを含むセクションを追加します。aPersonもaならCardHolderカードホルダー部分を見せたい。

私はこれを実装する方法に苦労しています。私が念頭に置いているのはUserRepository、指定された が であるかどうかPersonを尋ねることですUserUserその場合、メソッドはオブジェクトを返します。それ以外の場合は null。すべてのサブクラスでこれを行う予定です。

しかし、これはもっと良い方法で行うことができると感じていますが、その方法を見つけることができません。

編集:
次のシナリオがあります。私はオブジェクトの概要を持っていPersonます (派生物ではありません!)。行をクリックすると詳細ページを表示したい。このページには、上記のさまざまなセクションがあります。この時点で、「個人」がUser「カード所有者」でもあるかどうかを知りたいです。

ポリモーフィズムを適用したいのですが、方法がわかりません...

4

8 に答える 8

2

Ok, there are three things you can do in increasing order of preference.

1) Use "is" to explicitly check the class of the object. The problem with this approach is that it's brittle. If you come up with new subclasses in the future you need to change your condition. This breaks the "open/closed principle": you shouldn't need to modify code that exists in order to add new features.

2) Implement a "hasDetails" method in Person and override it in User. You then check "hasDetails" which you can then implement in any class that implements that interface. This is preferable because it allows you to add new code without changing existing code but is inflexible because it assumes that all details are the same.

3) "Tell, don't ask". Don't ask the object for information about itself and do something based on the result. Instead, tell the object to do the operation itself. This allows the object to decide when to do it and how to do it.

Using #3 is preferable in most cases but there are situations where you really have no choice but to go with #2 (eg. packaging or layering requires that the operation you want to perform can't be done by the Person object) or even with #1 (eg. you don't have access to the source code of the Person class or can't add methods to it).

于 2012-05-07T14:08:17.260 に答える
2

is演算子を使用できると思います:

if(Person is User) { /* do something */ }
if(Person is CardHolder) { /* do something more */ }

詳細はこちらをご覧 ください

ジェイソンがコメントしたように、あなたはおそらくこのような何か他のことをしたいと思うでしょう:

interface class Person
{
    IEnumerable<Section> GetSections();
}

class User : Person
{
     IEnumerable<Section> GetSections() { return new[] { new PersonSection() }; }
}

class CardHolder : Person
{
     IEnumerable<Section> GetSections() 
     { 
          return base.GetSections().Concat(new [] {new CardHolderSection() });
     }
}
于 2012-05-07T13:11:03.537 に答える
1

typeof (SubClass).IsSubclassOf(typeof (BaseClass));//trueを返します

于 2012-05-07T13:10:44.700 に答える
1

継承の代わりに集約を使用する方がよいでしょう。対応するプロパティが「null」であるかどうかに応じて、プロパティPerson.UserDataを作成し、コントロールを表示/非表示にします。Person.CardholderDetails

于 2012-05-07T13:11:13.473 に答える
0

たぶん私は要点を見逃しているかもしれませんが、あなたは「is」チェックを行うことができるはずだと思います:

var isUser = myObject is User;

MSDNを参照してください。

http://msdn.microsoft.com/en-us/library/scekt9xw%28v=vs.80%29.aspx

編集:

これは単純なソリューションであり、クラスを追加する場合はメンテナンスが必要になります。より良い答えについては、他の解決策を参照してください。

それが役に立てば幸い、

キリスト教徒

于 2012-05-07T13:11:08.383 に答える
0

次のシナリオがあります。Person オブジェクトの概要を説明しました (派生物ではありません!)。行をクリックすると詳細ページを表示したい。このページには、上記のさまざまなセクションがあります。この時点で、「Person」も aUser または aかどうかを知りたいですCardholder

enumを使用できます。したがって、次のようなことができます。

[Flags]    
public enum Test
{
    User,
    CardHolder
}

そして、それをクラスで使用します。

public class Person
{
    //...
    public Test MyTest;
}

そのため、好きな場所で使用できます。

Person person = new Person();
person.Test1 = (Test.User | Test.CardHolder);

//...

if(person.MyTest == Test.User | Test.CardHolder))
{
     //Do something
}

または単に:

Person person = new Person();
person.Test1 = Test.User;

//...

if(person.MyTest == Test.User)
{
     //Do something
}

if(person.MyTest == Test.CardHolder)
{ 
    //Do something
}
于 2012-05-07T13:28:08.397 に答える