C# 有没有办法从父类获取子类并检查(和使用)方法和属性?

C# 有没有办法从父类获取子类并检查(和使用)方法和属性?,c#,C#,我正在编写一个类,它将使用类并创建少量的信息报告。问题是,即使它们都从基类继承,这些子类也不必实现所有sames方法和属性。只是相关的 我不能强制转换这些类,因为在设计时我不知道将使用哪些类。。。我们有一个框架,在一个作业一个作业的基础上,开发人员接受它并实现一些特定于作业的代码。基类有一些必须实现的方法(Init、Report、Audit),但根据它是什么类型的作业,它将有几个属性中的一个或两个以及一两个方法。 所以(正如我下面简单的例子)他们可能实现Cat,但也需要第二个类,它与Cat相似,

我正在编写一个类,它将使用类并创建少量的信息报告。问题是,即使它们都从基类继承,这些子类也不必实现所有sames方法和属性。只是相关的

我不能强制转换这些类,因为在设计时我不知道将使用哪些类。。。我们有一个框架,在一个作业一个作业的基础上,开发人员接受它并实现一些特定于作业的代码。基类有一些必须实现的方法(Init、Report、Audit),但根据它是什么类型的作业,它将有几个属性中的一个或两个以及一两个方法。 所以(正如我下面简单的例子)他们可能实现Cat,但也需要第二个类,它与Cat相似,但不同程度足以保证一个新类,所以创建Cat2。 我知道这听起来很奇怪,但是当开发人员在使用框架时,他们正在使用他们的实例化类

class Animal
{
////common stuff
  public 
}

class Cat : Animal
{
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Meow");
  }
}
class Dog: Animal
{
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Woof");
  }
}
class Person: Animal
{
  public Title{ get; set; }
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Hello");
  }
}
class Spider: Animal
{
  public Name { get; set; }

}


List<Animal> animals = new List<Animals> {
  new Cat { Name = "Bob" },
  new Dog { Name = "Fido" },
  new Person { Name = "Harry", Title = "Mr" },
  new Spider { Name = "Boris" }
}

foreach (Animal item in animals)
{
  ///now is wishful pseudo code...
  if item has Speak then speak()
  if item has Title then write Title
  if item has Name then write Name
}
class Animal
{
    abstract Work();
}

class Cat : Animal
{
    public Name;
    public Speak();
    override Work()
    {
        Speak();
        Write Name;
    }
}
class Person: Animal
{
    public Title;
    public Name;
    public Speak();
    override Work()
    {
        Speak();
        Write Title;
        Write Name;
    }
}

foreach (Animal item in animals)
{
    item.Work();
}
类动物
{
////普通的东西
公开的
}
类别猫:动物
{
公共名称{get;set;}
公开演讲
{
控制台。书写线(“喵喵”);
}
}
狗类:动物
{
公共名称{get;set;}
公开演讲
{
控制台。书写线(“Woof”);
}
}
上课人:动物
{
公共标题{get;set;}
公共名称{get;set;}
公开演讲
{
Console.WriteLine(“你好”);
}
}
类别:动物
{
公共名称{get;set;}
}
列出动物=新列表{
新类别{Name=“Bob”},
新狗{Name=“Fido”},
新人{Name=“Harry”,Title=“Mr”},
新蜘蛛{Name=“Boris”}
}
foreach(动物中的动物项目)
{
///现在是一厢情愿的伪代码。。。
如果项目有Speak,则Speak()
如果项目有标题,则写标题
如果项目有名称,则写下名称
}
我只想循环浏览这个列表,如果它有某个属性,那么就阅读它。如果它有一个特定的方法,那么调用它

如果它有一个特定的属性,那么阅读它。如果它有一个特定的方法,那么调用它

听起来这些功能都定义了一个
接口
,即

interface IHazName{string Name{get;}
接口IHazTitle{string Title{get;}}
接口名称{void Speak();}
...
foreach(动物中的动物项目)
{
如果(项目为C)cs.Speak();
如果(项目名称为IHazTitle ht)写下(ht.Title);
如果(项目名称为IHazName hn)写下(hn.名称);
}
...
类别猫:动物,IHazName,ICanSpeak
{...}
狗类:动物,IHazName,我会说
{...}
上课人:动物,IHazName,IHazTitle,我会说
{...}
类蜘蛛:动物,名字
{...}
使用接口的一个特别好的地方是,您可以稍微捏造一下名称:

class狗:动物,IHazName,我会说
{
//...
public void Bark(){Say(“woof”);}//方法在公共API上称为Bark
void ICanSpeak.Speak()=>Bark();//但在ICanSpeak API上发言
}

注意:此处的用法如下:

如果(项目是ICanSpeak cs)cs.Speak();
需要现代C#编译器;如果您使用的是较旧的编译器,则:

if(item是icanstake)((icanstake)item.Speak();
或:

var cs=项目名称;
如果(cs!=null)cs.Speak();
同样地

Speak.Speak()=>Bark();
与旧编译器上的相同

Speak.Speak(){Bark();}

您可以添加一个新的抽象方法,然后在子类中实现它

class Animal
{
////common stuff
  public 
}

class Cat : Animal
{
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Meow");
  }
}
class Dog: Animal
{
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Woof");
  }
}
class Person: Animal
{
  public Title{ get; set; }
  public Name { get; set; }
  public Speak() 
  {
    Console.WriteLine("Hello");
  }
}
class Spider: Animal
{
  public Name { get; set; }

}


List<Animal> animals = new List<Animals> {
  new Cat { Name = "Bob" },
  new Dog { Name = "Fido" },
  new Person { Name = "Harry", Title = "Mr" },
  new Spider { Name = "Boris" }
}

foreach (Animal item in animals)
{
  ///now is wishful pseudo code...
  if item has Speak then speak()
  if item has Title then write Title
  if item has Name then write Name
}
class Animal
{
    abstract Work();
}

class Cat : Animal
{
    public Name;
    public Speak();
    override Work()
    {
        Speak();
        Write Name;
    }
}
class Person: Animal
{
    public Title;
    public Name;
    public Speak();
    override Work()
    {
        Speak();
        Write Title;
        Write Name;
    }
}

foreach (Animal item in animals)
{
    item.Work();
}

您可以创建一个静态列表,并将所有实例放入该列表中,以便进行检查。您可以使用类似
if(animal is Cat){/*use Cat with all Cat properties and methods*/}
,但通常不建议这样做。如果你经常使用它,它会指出建筑/设计中的问题这是一个新的ish特性(C#7?);以前,你可以这样做:
Cat=animalas-Cat;如果(cat!=null){[…]}
——另请参见:如果您“只是”想知道某个对象是否具有特定的属性和/或方法,反射可能会有所帮助,但这需要相当高的成本和性能。很抱歉延迟将其标记为正确答案。这真是一种享受,谢谢你。