通用ForEach方法,它接受相同类型的列表和值以及更改列表成员属性

时间:2017-12-12 09:46:52

标签: c# generics foreach

我有多个具有相同属性的类。我想创建一个单独的方法,为每个单独的类提供相同的目的。

示例:

 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?)

我试图找到一个有用的答案,但只能找到检索属性值的示例,而不是更改它。非常感谢任何建议。

3 个答案:

答案 0 :(得分:1)

您可以使用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);
    }
}

答案 1 :(得分:1)

创建名为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接口的任何类型,编译器不会抛出错误。

答案 2 :(得分:1)

其他答案很棒,但偶尔会出现无法使用界面装饰现有类的情况。例如,

  • 类定义在第三方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广泛使用。