Reputation: 465
consider the following code:
public interface IStuff<T>
{
IList<T> Items { get; set; }
bool IsExpanded { get; set; }
}
public interface IBar
{
string Name { get; set; }
}
public interface IFoo : IBar, IStuff<IBar>
{
}
public class MyClass : IFoo
{
public Name {get;set;
public IList<IBar> Items { get; set;}
bool IsExpanded { get; set; }
}
When I use this, what I'm actually going to do, is populate MyClass.Items
with instances of IFoo
, this is allowed as IFoo
implements IBar
, so all is good.
However there is a method that I'm working inside a control, which does not know and should not know about IBar
. It only needs to know about IStuff<>
Specifically that there is a list and a property.
When I'm working with the Items
, I'm going to detect if the item implements IStuff
like this.
public void ProcessItems( object item )
{
IStuff<object> stuff = item as IStuff<object>;
stuff.IsExpanded = true;
foreach( var childItem in stuff.items )
{
ProcessItems( childItem );
}
}
The problem here, is the cast into IStuff<object>
does not work now, it returns null.
What I want to do is work with the generic part of the interface only, I don't care about what the T
is.
The question is how do I replace
IStuff<object> stuff = item as IStuff<object>;
so that I can work with the items declared in the IStuff<>
interface?
Upvotes: 0
Views: 64
Reputation: 3542
If you don't mind reflection, you could read the property and cast it to IEnumerable
:
var listType = item.GetType().GetProperty("Items");
var enumerable = (IEnumerable)(listType.GetValue(item));
Likewise you could set the expanded flag.
Upvotes: 0
Reputation: 1424
Can you split IStuff
into a non-generic and generic parts (that inherits from the non-generic part) and then only deal with the non-generic part in your code? E.g.
public interface IStuff
{
IsExpanded { get; set; }
}
public interface IStuff<T> : IStuff
{
IList<T> Items { get; set; }
}
Upvotes: 0
Reputation: 37050
Sounds like you need co-variance on your interface IStuff
. However as IList<T>
is not co-variant you may use an interface that supports covariance such as IEnumerable<T>
which is co-variant since .NET 4.0:
public interface IStuff<out T>
{
IEnumerable<T> Items { get; set; }
bool IsExpanded { get; set; }
}
Now you can cast a an instance of IStuff<IBar>
to IStuff<object>
.
Upvotes: 3