1

我有一个Person基类和三个衍生物。在编辑页面上,我有一个包含一般人员数据(姓名、地址等)的部分。

我还希望每个子类有一个部分。因此,如果 aPerson是 a,User我想添加一个包含特定用户数据的部分。如果 aPerson也是 aCardHolder我想显示持卡人部分。

我正在努力解决如何实现这一点。我的想法是询问UserRepository指定的Person是否为User. 如果是,该方法将返回一个User对象;否则为空。我计划为所有子类执行此操作。

但是,我有这种感觉,这可以做得更好,但我找不到那种方法。

编辑:
我有以下情况。Person我对对象(不是派生词!)有一个概述。单击一行时,我想显示详细信息页面。在此页面上,我有如上所述的不同部分。在这一点上,我想知道“人”是否也是User“持卡人”。

我想应用多态性,但我不明白如何......

4

8 回答 8

2

在 Person 类上有一个抽象函数,称为“ ReturnValidSectionsForPerson()”。在每个子类中,重写该函数以根据需要返回“ UserData”或“ CardHolder”。您可以使用枚举来保存各种类型的部分,以使其更易于阅读和维护。

于 2012-05-07T13:09:56.267 回答
2

我认为您可以使用is运算符:

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

在这里阅读更多 。

正如 Jason 评论的那样,您可能还想做这样的事情:

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 回答
2

好的,您可以按照偏好的递增顺序执行三件事。

1)使用“is”明确检查对象的类。这种方法的问题在于它很脆弱。如果你将来想出新的子类,你需要改变你的条件。这打破了“开放/封闭原则”:您无需修改​​现有代码即可添加新功能。

2)在Person中实现一个“hasDetails”方法并在User中覆盖它。然后您检查“hasDetails”,然后您可以在任何实现该接口的类中实现它。这是可取的,因为它允许您在不更改现有代码的情况下添加新代码,但不灵活,因为它假定所有细节都是相同的。

3)“告诉,不要问”。不要向对象询问有关自身的信息,并根据结果做某事。相反,告诉对象自己执行操作。这允许对象决定何时执行以及如何执行。

在大多数情况下,最好使用#3,但在某些情况下,你真的别无选择,只能使用#2(例如,打包或分层要求你想要执行的操作不能由 Person 对象完成)甚至使用#1(例如,您无权访问 Person 类的源代码或无法向其添加方法)。

于 2012-05-07T14:08:17.260 回答
1

只需使用is运算符 - is 运算符用于检查对象的运行时类型是否与给定类型兼容。is 运算符用于以下形式的表达式:

if(pers is user )
{
}
else if (pers is cardholder)
{
}
于 2012-05-07T13:10:03.513 回答
1

typeof (SubClass).IsSubclassOf(typeof (BaseClass));// 返回真

于 2012-05-07T13:10:44.700 回答
1

最好使用聚合而不是继承。根据相应的属性是否为“空”来创建属性Person.UserData并显示/隐藏控件。Person.CardholderDetails

于 2012-05-07T13:11:13.473 回答
0

也许我错过了重点,但我认为您应该能够进行“是”检查:

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

您可以使用枚举。所以你可以做这样的事情:

[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 回答