我有多个类带有同一属性的类。我想创建一个单个方法的单个方法。
示例:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem)
{
foreach (var item in itemList)
{
item.IsSelected = selectedItem.Equals(item);
}
}
正如预期的,我收到此错误:
'T' does not contain a definition for 'IsSelected' and no extension method 'IsSelected' accepting a first argument of type 'T' could be found (are you missing a using directive or an assembly reference?)
我试图找到一个有用的答案,但只能找到检索属性值而不是更改属性值的示例。任何建议都非常感谢。
创建一个称为 IIsSelected
public interface IIsSelected
{
bool IsSelected { get; set; }
}
然后在具有IsSelected
属性的类上实现此接口:
public class MySelectableClass : IIsSelected
{
public bool IsSelected { get; set; }
}
将您的方法更新为:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem)
where T: IIsSelected
{
foreach (var item in itemList)
{
item.IsSelected = selectedItem.Equals(item);
}
}
该方法仅将除了任何实现IIsSelected
接口和编译器的类型都不会引发错误。
您可以使用Interface
并装饰您的类以支持ISSELECTED
public interface ISelectable
{
bool IsSelected { get; set; }
}
public class MyAwesomeClass : ISelectable
{
public bool IsSelected { get; set; }
// Blah
}
private void RefreshSelection<T>(ObservableCollection<ISelectable> itemList, T selectedItem)
where T : class, ISelectable
{
foreach (var item in itemList)
{
item.IsSelected = selectedItem.Equals(item);
}
}
其他答案很棒,但是有时在某些情况下,您无法用接口装饰现有类。例如,
- 类定义在第三方DLL中,
- 您没有团队负责人的许可。
在这些情况下,将属性集移到您的功能外,将其作为lambda函数传递:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem,
Action<T, bool> setSelected)
{
foreach (T item in itemList)
{
setSelected(item, selectedItem.Equals(item));
}
}
并以这种方式称呼:
RefreshSelection(itemList, selectedItem, (i, newValue) =>
{
i.IsSelected = newValue;
});
这是用于重复使用代码的标准技术 - Linq和jQuery广泛使用。