访问通用类中的属性

问题描述 投票:0回答:1

假设我有这样一个类:

    public class DepartmentBase<T> : MyBase where T : new()
    {
        public ObservableCollection<T> Employees
        {
           get { return _employees; }
           set { _employees = value; OnPropertyChanged(); }
        }
        private ObservableCollection<T> _employees;
    
        public T Selected_employee
        {
            get { return _selected_employee; }
            set { _selected_employee = value; OnPropertyChanged(); }
        }
        private T _selected_employee;
        
        public void AddEmployee(object parameter)
        { 
           //Using dynamic - each type T has those 3 properties        
           dynamic new_employee = new T();
           new_employee.NEW = true;
           new_employee.START_DATE = DateTime.Now;
    
           Employees.Add(new_employee);
           
           //Using reflection with Read() and Set() methods, to set each T item property "NEW" to false
           Employees.Where(a => (bool)a.Read("NEW") == true).ToList().ForEach(b => b.Set("NEW", false));
    
           Selected_employee = Employees.Last();
        }
    }

如您所见,void AddEmployees 需要以两种不同的方式直接处理 T 类型的属性。

在第一行中,我使用 dynamic 关键字将项目添加到集合中。这使我能够编写那样的代码。

之后我在 Collection 上使用 Linq,其中某些属性符合条件。为此,我使用reflection.

这两种方式都在运行时解决(据我所知),这会影响性能。

我的问题是:如何访问泛型类中的属性,使我可以像使用 dynamic 关键字一样编写代码,但也可以使用 Linq 以相同的方式工作并保持所有内容匿名,以便代码在编译时解析?

c# dynamic system.reflection anonymous-types
1个回答
2
投票

如何访问泛型类中的属性,使我可以像使用 dynamic 关键字一样编写代码,但也可以使用 Linq 以相同的方式工作并保持所有内容匿名,以便代码在编译时解析?

通过在类型参数上添加约束

public class DepartmentBase<T> : MyBase where T : IModel, new()
{
    public ObservableCollection<T> Employees
    {
        get { return _employees; }
        set { _employees = value; OnPropertyChanged(); }
    }
    private ObservableCollection<T> _employees;

    public T Selected_employee
    {
        get { return _selected_employee; }
        set { _selected_employee = value; OnPropertyChanged(); }
    }
    private T _selected_employee;

    public void AddEmployee(object parameter)
    {
        T new_employee = new T();
        new_employee.NEW = true;
        new_employee.START_DATE = DateTime.Now;

        Employees.Add(new_employee);

        //Using reflection with Read() and Set() methods, to set each T item property "NEW" to false
        Employees.Where(a => (bool)a.Read("NEW") == true).ToList().ForEach(b => b.Set("NEW", false));

        Selected_employee = Employees.Last();
    }
}

IModel
是一个接口(或类),您与
DepartmentBase<T>
一起使用的任何类型都必须实现:

public interface IModel
{
    bool NEW { get; set; }
    DateTime START_DATE { get; set; }

    bool? Read(string s);
    void Set(string s, bool b);
}
© www.soinside.com 2019 - 2024. All rights reserved.