2017-06-06 26 views
0

我正在与几个具有相同父类的子类一起工作。我想给一个可以是其中一个子类的函数提供一个对象,然后创建一个子类类型,然后直接寻找相应的子类属性。验证所需的继承后,是否可以解决子类属性?

class human 
{ 
    public string name; 
} 

class woman : human 
{ 
    public bool isPregnant; 
} 

class man : human 
{ 
    public int numberOfComputers; 
} 

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Console.WriteLine("Hello World!"); 
     man Andrew = new man(); 
    } 

    public void checkHuman<T>(T my_human) where T : human 
    { 
     // is something like this possible?? 
     if (typeof(my_human).Name == "woman") 
      Console.WriteLine(my_human.name & " is " & (my_human.isPregnant ? "pregnant." : "not pregnant.")); 
     if (typeof(my_human).Name == "man") { 
      man m = (man)my_human; 
      Console.WriteLine(m.name & " has " & m.numberOfComputers & " computers."); 
     } 
    } 
} 
+0

粉饰Java风格的命名约定......在一般情况下,如果你发现自己有根据实际类型的通用变量来编写自定义的逻辑,还有你使用一个很好的机会泛型错了。但是回到你的问题,是的,'typeof(T).Name'可以得到你传入的实际类型。'typeof'是一个只保留类型而不是变量的关键字。所以你不能在'my_human'上运行它。相当于'my_human.GetType()。Name' – PoweredByOrange

+0

您还应该查看'is'和'as'运算符。 –

回答

1

你不应该真的在那里使用泛型。相反,你只是想接受任何人的对象(记住,ManWoman也有效Human对象),并使用is运营商检查具体类型:

public void CheckHuman(Human human) 
{ 
    if (human is Woman) 
    { 
     var woman = (Woman)human; 
     Console.WriteLine("{0} is {1}pregnant.", woman.Name, woman.IsPregnant ? "" : "not "); 
    } 
    else if (human is Man) 
    { 
     var man = (Man)human; 
     Console.WriteLine("{0} has {1} computers.", man.Name, man.NumberOfComputers); 
    } 
} 

可以ALS使用C#7算子的模式在这里自动转换的对象为正确的类型:

public void CheckHuman(Human human) 
{ 
    if (human is Woman woman) 
    { 
     Console.WriteLine("{0} is {1}pregnant.", woman.Name, woman.IsPregnant ? "" : "not "); 
    } 
    else if (human is Man man) 
    { 
     // please keep in mind that women have computers too 
     Console.WriteLine("{0} has {1} computers.", man.Name, man.NumberOfComputers); 
    } 
} 

请注意,我调整了您的类型和成员的一般命名:类名,方法和属性都应该使用PascalCase,而变量和字段使用驼峰。

3

肯定有可能检查一个对象的类型,转换为该类型并访问子属性。然而,这样做是一种“气味”,并表明你的抽象是不正确的。

相反,您应该在父类中定义常见的预期行为,然后在每个子类中实现它。这样你的调用代码就不需要知道它调用的确切的子类,而是依赖于父类提出的合同。

using System; 

public abstract class Human 
{ 
    public string Name; 

    public abstract string GetDetails(); 
} 

public class Woman : Human 
{ 
    public bool IsPregnant; 

    public override string GetDetails() 
    { 
     return Name + " is " + (IsPregnant ? "pregnant." : "not pregnant."); 
    } 
} 

public class Man : Human 
{ 
    public int NumberOfComputers; 

    public override string GetDetails() 
    { 
     return Name + " has " + NumberOfComputers + " computers."; 
    } 
} 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var andrew = new Man 
     { 
      Name = "Andrew", 
      NumberOfComputers = 200 
     }; 

     OutputDetails(andrew); 
    } 

    public static void OutputDetails(Human myHuman) 
    { 
     Console.WriteLine(myHuman.GetDetails()); 
    } 
} 
0
public void checkHuman<T>(T my_human) where T : human 
{ 

    var woman = my_human as woman; 
    if (woman != null) 
    { 
     Console.WriteLine(string.Format("{0} is {1}", woman.name, woman.isPregnant ? "pregnant." : "not pregnant.")); 
    } 
    else 
    { 
     var man = my_human as man; 
     Console.WriteLine(string.Format("{0} has {1} computers", man.name, man.numberOfComputers)); 
    } 
}