Reputation: 981
I'm trying to check if something is an interface and I'm not sure I'm going about it the correct way. I have the underlying interface that I want to check against:
interface IName
{
string Name {get;}
}
I then have a class that implements this interface:
class Person : IName
{
public string Name {get;}
}
I then have another interface:
interface IThing<T>
{
T Thing {get;}
}
I then have another class that implements IThing:
class Teacher : IThing<Person>
{
public Person Thing {get;}
}
What I want to be able to do is this:
Teacher teacher = new Teacher("Math", "John");
if (teacher is IThing<IName>)
{
Console.WriteLine((teacher as IThing<IName>).Thing.Name);
}
This doesn't work however. I'm pretty sure it can't figure out that IThing<Person>
is an IThing<IName>
. How do I accomplish this? I basically have several classes that implement the IThing<BaseClassThatIsIName>
so I don't want to explicitly cast to the type, but rather the interface.
Upvotes: 0
Views: 89
Reputation: 134811
The problem is that you're specifically trying to see if the teacher implements the IThing<IName>
interface. It doesn't however, it implements the IThing<Person>
interface where Person
implements the IName
interface. You're looking for some covariance here but the way you've defined the IThing<>
interface doesn't allow for it. Allow for it:
interface IThing<out T> // note the "out" in the parameter
{
T Thing { get; }
}
Now the interface will match exact parameter types or more general types. You should be able to do what you want now:
if (teacher is IThing<IName>) // teacher is actually a `IThing<Person>` but
// `Person` is an `IName` so we're good
{
Console.WriteLine((teacher as IThing<IName>).Thing.Name);
}
Upvotes: 1
Reputation: 1391
I believe you've nailed the problem on the head, and I'm not sure there's a way around it just using the "is" keyword. However, you could use reflection to check that 1) teacher is generic, 2) teacher's generic type is IThing, 3) teacher's generic type has one type parameter, and 4) that first parameter inherits from IName.
Read through this documentation to get you started.
Upvotes: 0