提问人:Lucy82 提问时间:4/13/2023 最后编辑:AShLucy82 更新时间:4/14/2023 访问量:32
访问泛型类中的属性
Access properties in generic class
问:
假设我有一个这样的类:
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 需要以 2 种不同的方式直接处理 T 类型的属性。
在第一行中,我使用动态关键字将项目添加到集合中。这使我能够编写这样的代码。
之后,我在 Collection 上使用 Linq,其中某些属性符合条件。为此,我使用反射。
这两种方式都在运行时得到解决(据我所知),这会影响性能。
我的问题是:如何以一种我可以像使用动态关键字一样编写代码的方式访问泛型类中的属性,但也可以使用 Linq 以相同的方式工作并保持所有内容匿名,以便代码在编译时解析?
答:
2赞
mm8
4/13/2023
#1
如何以一种我可以像使用动态关键字一样编写代码的方式访问泛型类中的属性,但也可以以相同的方式使用 Linq 并保持所有内容匿名,以便代码在编译时解析?
通过在 type 参数上添加约束:
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);
}
评论
2赞
Ralf
4/13/2023
我认为 Read 方法只是一些“工具”,向我们展示了他在 LINQ 语句中获取 NEW 属性的困难。现在您已经修复了它,LINQ 语句可以简单地使用 NEW 属性。
1赞
Lucy82
4/13/2023
@mm8,耶稣基督,这是我在阅读其他帖子时首先尝试的。但是你的最后一句话“你与 DepartmentBase<T> 一起使用的任何类型都必须实现”为我确定了它。我在错误的地方这样做 - 我在继承 DepartmentBase<T> 的类上实现了接口,而不是在类型上!...多谢!!!顺便说一句 - 不需要读取和设置,Linq 在没有它的情况下工作相同(尽管通过接口在相同的属性上):)
0赞
mm8
4/13/2023
@Ralf:没错。我显然没有很好地阅读问题中的代码,无法自己弄清楚:)
1赞
mm8
4/13/2023
对于具有类型参数的泛型类型,如果您希望能够对该类型的实例执行一些“特定”操作,例如设置或比较属性,则使用约束是正确的方法。T
T
T
1赞
mm8
4/13/2023
另一种选择是跳过泛型和编译时安全性,而是使用通用基类型(如 ),然后尝试在运行时强制转换参数。object
下一个:C# 从数组字符串生成匿名类型
评论