2010-06-07 2 views
2

Мне нужно включить общий список конкретного типа в общий список интерфейса, который реализуют конкретные типы. Этот список интерфейсов является свойством объекта, и я присваиваю значение с помощью отражения. Я знаю только значение во время выполнения. Ниже приведен простой пример кода, что я пытаюсь сделать:.net runtime type casting при использовании отражения

public void EmployeeTest() 
    { 
     IList<Employee> initialStaff = new List<Employee> { new Employee("John Smith"), new Employee("Jane Doe") }; 
     Company testCompany = new Company("Acme Inc"); 
     //testCompany.Staff = initialStaff; 

     PropertyInfo staffProperty = testCompany.GetType().GetProperty("Staff"); 
     staffProperty.SetValue(testCompany, (staffProperty.PropertyType)initialStaff, null); 
    } 

Классы определяются следующим образом:

public class Company 
{ 
    private string _name; 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    private IList<IEmployee> _staff; 

    public IList<IEmployee> Staff 
    { 
     get { return _staff; } 
     set { _staff = value; } 
    } 

    public Company(string name) 
    { 
     _name = name; 
    } 
} 

public class Employee : IEmployee 
{ 
    private string _name; 

    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    public Employee(string name) 
    { 
     _name = name; 
    } 
} 

public interface IEmployee 
{ 
    string Name { get; set; } 
} 

Любые мысли?

Я использую .NET 4.0. Помогли бы новые ковариантные или контравариантные функции?

Заранее спасибо.

ответ

3

Нет, .NET 4 variance здесь не поможет: IList<T> является инвариантным, поскольку значения идут как внутри, так и снаружи (вы можете добавлять элементы, и вы можете их получить).

В принципе, этот приведение не будет работать (если вы не используете массив и его свойства дисперсии, это просто ужасно). Сам листинг не нужен - SetValue просто принимает object - но попытка установить свойство с неправильным типом не удастся.

Вы можете создать новый список нужного типа - но это значит, что он будет отделен от существующего списка. Это приемлемо? (Элементы списка сами будут разделяться, но если вы добавите новый элемент в один список, это не будет отображаться в другом.)

+0

Список будет новым, но сотрудники будут такими же старыми объектами – SWeko

+0

@SWeko: Абсолютно. Будет редактировать, чтобы сделать это яснее. –

+0

Чтобы дополнительно усложнить этот вопрос, Staff является IList, поэтому вы не можете просто создать его экземпляр и добавить новые элементы, вы также должны знать желаемую реализацию ... – SWeko