下面的控制台应用程序编译,但界面转换在运行时失败。是否有一种简单的方法可以使这项工作?
namespace ConsoleApplication1
{
class Monkey
{
public string Shock { get { return "Monkey has been shocked."; } }
}
static class MonkeyExtensionToSupportIWombat
{
public static string ShockTheMonkey( this Monkey m )
{
return m.Shock;
}
}
interface IWombat
{
string ShockTheMonkey();
}
class Program
{
static void Main( string[] args )
{
var monkey = new Monkey();
Console.WriteLine( "Shock the monkey without the interface: {0}", monkey.Shock );
IWombat wombat = monkey as IWombat;
Console.WriteLine( "Shock the monkey with the interface: {0}", wombat.ShockTheMonkey() );
Console.ReadLine();
}
}
}
答案 0 :(得分:3)
猴子不是来自IWombat,所以我不确定你为什么会这样做(除了使用反射或动态调用之外,但是这会对类设计中的基本缺陷造成影响) 。 如果你想让它工作,你必须让Monkey实现IWombat,或者让另一个继承自实现IWombat的Monkey的类(如下所示)。
class Monkey
{
public string Shock { get { return "Monkey has been shocked."; } }
}
static class MonkeyExtensionToSupportIWombat
{
public static string ShockTheMonkey(this Monkey m)
{
return m.Shock;
}
}
interface IWombat
{
string ShockTheMonkey();
}
class MonkeyBat : Monkey, IWombat
{
#region IWombat Members
public string ShockTheMonkey()
{
return this.Shock;
}
#endregion
}
class Program
{
static void Main(string[] args)
{
var monkey = new Monkey();
Console.WriteLine("Shock the monkey without the interface: {0}", monkey.Shock);
var monkeyBat = new MonkeyBat();
Console.WriteLine("Shock the monkey with the interface: {0}", monkeyBat.ShockTheMonkey());
Console.ReadLine();
}
}
答案 1 :(得分:1)
当Monkey没有实现IWombat时,强制转换将始终失败。但这与扩展方法没有关系。你想做什么?
答案 2 :(得分:0)
我不是扩展方法方面的专家,但我认为你要做的是编程相当于混合隐喻。基本上引入了扩展方法,以便有人能够访问类的源可以扩展类的功能。通过说某些东西实现了一个接口,你基本上说你有权访问来源,所以真的不需要扩展方法。如果作为类的设计者,您希望该类的使用者指定功能,那么使用Monkey.ShockTheMonkey调用委托会更合适吗?
答案 3 :(得分:0)
强制转换失败,因为Monkey没有实现IWombat。演员总是会失败。
看起来他正试图能够在接口上使用这些方法而不实际实现接口。从最纯粹的意义上讲,这是不可能的。尽管如此,它们可能是一些蠢事,但我不认为这是值得的。