我有一个班级:
public class Person {
public string FirstName = "";
public string LastName = "";
}
和派生类:
public class HRPerson : Person {
public string GetSomething() {
//calculate something
}
}
基本上,我想扩展基类的功能。使用情况如下所示,其中GetAllPerson
返回List<Person>
。
class Program
{
static List<HRPerson> GetAllHRPerson()
{
List<HRPerson> HRPersonList = new List<HRPerson>();
foreach (Person person in GetAllPerson)
{
HRPersonList.Add(person);
}
return HRPersonList;
}
}
它没有编译,说参数没有重载,当我尝试将人员转换为HRPerson
时,我得到运行时错误“无法转换Person
类型的对象输入HRPerson
“错误。
如何添加此类附加功能?
答案 0 :(得分:6)
听起来你的GetAllPerson
正在回归一些非人力资源人员......
假设情况如此,您只想过滤掉这些,最简单的方法是使用LINQ的OfType
方法:
static List<HRPerson> GetAllHRPerson()
{
return GetAllPerson().OfType<HRPerson>().ToList();
}
(旁注:除了常量之外,请避免使用像这样的公共字段。字段应该是实现细节,而不是公共API的一部分。)
当然,如果您的Person
个实例中没有一个实际上是HRPerson
的实例,那么这对您没有帮助。您无法在创建实例后更改其类型。您的情况并不十分清楚 - 如果这个答案对您没有帮助,请提供更多详细信息。
编辑:我还不确定你想要一个扩展方法,但如果你这样做,那就像是:
public static class PersonExtensions
{
public static string GetSomething(this Person person)
{
// Do something with the given Person
}
}
然后,您可以在任何Person
上调用它,就好像它是一个实例方法:
Person person = ...;
string something = person.GetSomething();
但这不是不多态 - 并不是因为你正在改变Person
对象的任何内容,你的描述仍然让它听起来像你真正想要的做...
答案 1 :(得分:0)
根据你对Jon Skeet的回答,这就是你要找的东西:
创建Person的子类,例如NamedPerson。给NamedPerson一个方法GetFullName,它返回Person的全名。
然后从NamedPerson创建子类HRPerson,并重写GetFullName以稍微不同的格式返回名称。 CCPerson也将被命名为NamedPerson。
您无法控制Person,但您可以完全控制NamedPerson。然后你想要的是NamedPersons列表,而不是HRPersons列表。此列表可以包含裸NamedPersons,或HRPersons,或CCPersons,但列表中的所有对象都是NamedPersons或它的子类,因此它们都将具有GetFullName。