Given this code snippet that can be readily pasted into Linqpad (or slightly modified in a Visual Studio console solution):
void Main()
{
var cat = this.GetCat();
var dog = this.GetDog();
cat.Think();
cat.ThinkHarder();
//dog.Think(); // Does not compile.
//dog.ThinkHarder(); // Does not compile.
//if ([dog is returned as ISmartAnimal]) // What to put here?
((ISmartAnimal)dog).Think(); // Compiles, runs, but shouldn't.
reportTypeProperties(cat);
reportTypeProperties(dog);
}
interface IAnimal
{
string Name { get; set; }
}
interface ISmartAnimal : IAnimal
{
void Think();
}
class Animal : IAnimal, ISmartAnimal
{
public string Name { get; set; }
public void Think() { }
}
ISmartAnimal GetCat()
{
return new Animal();
}
IAnimal GetDog()
{
return new Animal();
}
static void reportTypeProperties(object obj)
{
var type = obj.GetType();
Console.WriteLine("Type: {0}", type.Name);
Console.WriteLine("Is smart? {0}", obj is ISmartAnimal);
}
static class ext
{
public static void ThinkHarder(this ISmartAnimal animal)
{ }
}
The output of reportTypeProperties
shows that dog
, although returned as IAnimal, "is" an ISmartAnimal. (Same for both objects)
Type: Animal
Is smart? True
This is because GetType()
returns the concrete type of the object, not its current interface.
My question. Is there a way to tell that dog
is returned as IAnimal? (see pseudocode). The compiler knows (so does quickview). Suppose I had some animal object and I wanted to inspect in runtime code whether or not I can make it Think()
.
Background:
This may seem an academic exercise. And it may seem strange to have a class (Animal) implement an interface (ISmartAnimal) that you don't want to expose always. But I ask because I encountered something similar in Entity Framework. If you want you can read about it here, but it diverts to EF-specific features. If you don't want to delve into that it suffices to say that it's imperative that Animal
implement both interfaces.
Disclaimer:
"Any resemblance to real animals is purely coincidental :)"
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…