Reputation: 996
I have multiple classes with the same property. I want to create a single method that would serve the same purpose for each individual class.
Example:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem)
{
foreach (var item in itemList)
{
item.IsSelected = selectedItem.Equals(item);
}
}
As expected, I recieve this error:
'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?)
I have tried to find a useful answer but can only find examples of retrieving the property value, not changing it. Any advice is greatly appreciated.
Upvotes: 0
Views: 53
Reputation:
The other answers are great, but occasionally there are situations where you cannot decorate existing classes with an interface. For example,
For these situations, move the property-set outside your function, passing it in as a lambda function instead:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem,
Action<T, bool> setSelected)
{
foreach (T item in itemList)
{
setSelected(item, selectedItem.Equals(item));
}
}
and call it this way:
RefreshSelection(itemList, selectedItem, (i, newValue) =>
{
i.IsSelected = newValue;
});
This is a standard technique for reusing code - extensively used by Linq and jQuery.
Upvotes: 1
Reputation: 81493
You could use an Interface
and decorate your classes that support 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);
}
}
Upvotes: 1
Reputation: 732
Create an interface called IIsSelected
public interface IIsSelected
{
bool IsSelected { get; set; }
}
Then implement this interface on your classes which has the IsSelected
property:
public class MySelectableClass : IIsSelected
{
public bool IsSelected { get; set; }
}
Update your method to:
private void RefreshSelection<T>(ObservableCollection<T> itemList, T selectedItem)
where T: IIsSelected
{
foreach (var item in itemList)
{
item.IsSelected = selectedItem.Equals(item);
}
}
The method will only except any type which implements the IIsSelected
interface and the compiler won't throw an error.
Upvotes: 1