【问题标题】:.net runtime type casting when using reflection使用反射时的.net运行时类型转换
【发布时间】:2011-02-28 17:00:03
【问题描述】:

我需要将具体类型的通用列表转换为具体类型实现的接口的通用列表。此接口列表是对象的属性,我正在使用反射分配值。我只知道运行时的值。下面是我想要完成的一个简单的代码示例:

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。新的协变或逆变特征会有所帮助吗?

提前致谢。

【问题讨论】:

    标签: .net generics reflection properties


    【解决方案1】:

    不,.NET 4 变体在这里没有帮助:IList&lt;T&gt; 是不变的,因为值既可以输入也可以输出(您可以添加项目并获取它们)。

    基本上这种转换是行不通的(除非你使用一个数组和它的方差属性;不过这太可怕了)。强制转换本身不是必需的 - SetValue 只需要 object - 但尝试使用错误类型设置属性将失败。

    您可以构建一个正确类型的列表——但这意味着它将与现有列表分开。这可以接受吗? (列表元素本身是共享的,但如果您将新元素添加到一个列表中,它将不会显示在另一个列表中。)

    【讨论】:

    • 列表将是新的,但员工将是相同的旧对象
    • 更复杂的是,Staff 是一个 IList,所以你不能只是实例化它,然后添加新元素,你也必须知道所需的实现......
    • @SWeko:确实 - 我假设 List&lt;T&gt; 就足够了 :)
    猜你喜欢
    • 2012-01-13
    • 2022-11-29
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    相关资源
    最近更新 更多