2013-03-19 3 views
1

У меня есть класс:как расширить функциональные возможности базового класса

public class Person { 
    public string FirstName = ""; 
    public string LastName = ""; 
} 

и производный класс:

public class HRPerson : Person { 
    public string GetSomething() { 
     //calculate something 
    } 
} 

Essentilly, я хотел расширить функциональные возможности базового класса. Использование выглядит так, где 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 возвращаются некоторые не HR людей ...

Если предположить, что это так, и вы просто хотите, чтобы отфильтровать те из, это простое в использовании OfType метода LINQ в:

static List<HRPerson> GetAllHRPerson() 
{ 
    return GetAllPerson().OfType<HRPerson>().ToList(); 
} 

(Обратите внимание: пожалуйста, избегайте публичных полей, подобных этому, кроме констант. Поля должны быть деталями реализации, а не частью вашего общедоступного API.)

Конечно, если ни один из ваших Person экземпляров на самом деле являются экземплярами HRPerson, это не поможет вам. Вы не можете изменить тип экземпляра после его создания. Не совсем ясно, какова ваша ситуация - если этот ответ вам не поможет, предоставьте более подробную информацию.

EDIT: Я до сих пор не совсем уверен, что вы хотите метод расширения, но если вы делаете, это будет что-то вроде:

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 объекта, ваше описание еще делает его звук, как вы действительно хотите d О ...

+0

GetAllPerson возвращает список Person. – Tremour101

+0

@ Tremors101: Ну, тогда как вы ожидали, что это сработает? Если ни одна из ссылок на самом деле не относится к «HRPerson», как вы ожидали, что она будет создана? –

+0

Это уменьшенный пример. Идея состоит в том, что разные клиентские коды могут иметь разные версии класса Person. например HRPerson.GetFullName может возвращать 'LName, FName', тогда как CCPerson.GetFullName может возвращать 'FName LName', и у меня нет никакого контроля над классом Person, а Person.GetFullName не существует – Tremour101

0

На основании ваших комментариев к ответу Джона Скита, это то, что вы ищете:

Создать подкласс Person, например, NamedPerson. Дайте NamedPerson метод GetFullName, который возвращает полное имя Person.

Затем создайте подкласс HRPerson из NamedPerson и переопределите GetFullName, чтобы вернуть имя в немного другом формате. CCPerson также будет подклассифицирован из NamedPerson.

У вас нет контроля над Лицом, но у вас есть полный контроль над NamedPerson. Тогда вам нужен список NamedPersons, а не HRPersons. Этот список может содержать голые NamedPersons, HRPersons или CCPersons, но все объекты в списке будут NamedPersons или подклассы, поэтому у всех будет GetFullName.

+0

Итак, когда я получаю список Лица из моего датапровайдера, как мне заставить их быть NamedPerson? Подкласс, вы имеете в виду: Class NamedPerson: Person {} – Tremour101

+0

Если вы получаете Person из какого-то места и не имеете никакого контроля над ним и хотите добавить подклассы с помощью методов базового класса, то одна вещь, которую вы можете сделать, это создать NamedPerson, который имеет Лицо как член. Это не подкласс - это новый базовый класс, в котором есть Человек внутри него. Затем выведите NamedPerson.GetFullName и сделайте все свои подклассы из NamedPerson. –

Смежные вопросы