2017-07-07 83 views
1

我有三个名为Person,City和District的类,以及其他一些类。确定作为参数发送的对象类型

我发送这三个类中的一个作为函数参数。我想做一个手术取决于这三个人中的哪一个已经被发现。我怎样才能做到这一点?所有这三个类都扩展了一个实体类。

现在是这样的:

public void Insert (City newCity) 

但我想它是这样的:

public void Insert (Entity e) 

或类似的东西,而且无论它是(市或人),我想用它的属性。

谢谢!

+3

假设多态性是不可能的(即'e.DoTheThing(..如果(e是City){...} else if(e是Person){...}否则if(e是District){...}'? –

+0

这里有点难以猜出你在做什么,没有更多的代码。但是看看'is'或'as'运算符来确定你正在处理的是哪一种类型/类。 –

+0

为什么不只是使用'Insert'的三个重载?对一个方法的参数做类型检查看起来很奇怪,而不是仅仅为每个实体使用不同的方法...... – Chris

回答

4

你可以使它通用:

public void Insert<T>(T entity) where T: Entity 
{ 

} 

现在你可以使用所有属性或Entity方法。如果您需要使用仅属于亚型属性或方法,你要投它:

public void Insert<T>(T entity) where T: Entity 
{ 
    if(entity is City) 
    { 
     City city = (City) entity; 
     // ... 
    } 
    else if(entity is Person) 
    { 
     Person person = (Person) entity; 
     // ... 
    } 
} 
+0

好的解决方案,但是op想要访问它们不会像这样工作的属性,您需要投射。至少这就是我的理解 – EpicKip

+0

@EpicKip:除非你重载方法,否则没有别的选择。尽管铸造有什么错误? –

+0

@VisualVincent呃...因为首先它只是说你可以使它通用,而不是完整的修复。现在帖子已经更新,涵盖了一切。我是说铸件没有被覆盖 – EpicKip

2

只需使用isas运营商在这样:

public void Insert(Entity e) 
{ 
    if (e is Person) 
    { 
     Person tmp = e as Person; 
     //do your code 
    } 
    else if (e is City) 
    { 
     City tmp = e as City; 
     //do your code 
    } 
    else if(e is District) 
    { 
     District tmp = e as District; 
     //do your code 
    } 
} 
0

一种方法是使用继承和铸造,像这样:

 public abstract class Entity 
     { 
      public int Id { get; set; } 
     } 

     public class City : Entity 
     { 
      public string CityName { get; set; } 
     } 

     public class Person : Entity 
     { 
      public string PersonName { get; set; } 
     } 

     public class MethodHost 
     { 
      public void Insert(Entity e) 
      { 
       if (e is Person person) 
       { 
        // Do something with person 
       } else if (e is City cityName) 
       { 
        // Do something with city 
       } 
      } 
     } 

PS :我使用了一些新的C#的功能在这里,如果您使用的是C#的旧版本,你可能需要做这样的事情:

var city = e as city 
if(city != null) 
{ 
    // Do something with city 
} 

您还可以使用在如投下内,如果-ta gs--但这不是最高效的方式,因为它投了两次而不是一次。

0

最好的办法是实施不同的方法。如果他们内部有一些通用逻辑,就把它带到不同的方法并调用它。

public void Insert (City newCity) 
{ 
    // TODO logic for City 
} 

public void Insert (Entity e) 
{ 
    // TODO logic for Entity 
} 

另一种方法是继承。如果城市可以从实体好过得出这样来做:

public class Entity 
{ 
    public virutal void Insert (Entity e) 
    { 
     // TODO logic for Entity 
    } 
} 

public class City : Entity 
{ 
    public override void Insert (City city) 
    { 
     // TODO logic for City 
    } 
} 
0

在C#7.0,你可以使用模式匹配

public void Insert(Entity e) 
{ 
    switch (e) 
    { 
     case Person p: 
      Console.WriteLine("Insert Person"); 
      break; 
     case City c: 
      Console.WriteLine("Insert City"); 
      break; 

     default: 
      Console.WriteLine("<other>"); 
      break; 
    } 
}