检查子类是否属于特定类型的最佳方法是什么?

时间:2012-05-07 13:07:47

标签: c# oop asp.net-mvc-2

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

我还想要每个子类的一个部分。因此,如果PersonUser,我想添加包含特定用户数据的部分。如果Person也是CardHolder我想要显示持卡人部分。

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

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

修改
我有以下场景。我概述了Person个对象(不是衍生物!)。单击一行时,我想显示详细信息页面。在这个页面上,我有如上所述的不同部分。此时我想知道'人'是否也是User或'持卡人'。

我想应用多态,但我不知道如何......

8 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

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

了解更多here

正如杰森评论的那样,你可能想做一些像这样的事情:

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() });
     }
}

答案 2 :(得分:2)

好的,你可以做三件事来增加偏好的顺序。

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

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

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

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

答案 3 :(得分:1)

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

if(pers is user )
{
}
else if (pers is cardholder)
{
}

答案 4 :(得分:1)

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

答案 5 :(得分:1)

最好使用聚合而不是继承。使属性Person.UserDataPerson.CardholderDetails显示/隐藏控件,具体取决于相应的属性是否为“null”。

答案 6 :(得分:0)

也许我错过了这一点,但我认为你应该可以做一个“是”检查:

var isUser = myObject is User;

请参阅MSDN:

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

编辑:

这是一个简单的解决方案,如果添加更多类,则需要维护。请参考其他解决方案以获得更好的答案。

希望它有所帮助,

基督教

答案 7 :(得分:0)

  

我有以下情况。我对Person对象有一个概述   (不是衍生品!)。单击一行时,我想显示   详情页面。在这个页面上,我有不同的部分描述   以上。此时我想知道'人'是否也是User   或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
}