C# 接口引用如何能够调用子类方法?

C# 接口引用如何能够调用子类方法?,c#,oop,C#,Oop,接口引用如何能够调用子类方法 在下面的例子中 接口引用如何访问测试类对象 interface ITest { int add(); } public class Test : ITest { public int add() { return 1; } public int sub() { return -1; } } static void Main(string[] args) { ITest t = new Test();

接口引用如何能够调用子类方法

在下面的例子中 接口引用如何访问测试类对象

interface ITest
{
  int add();
}

public class Test : ITest
{
  public int add()
  {
    return 1;
  }
  public int sub()
  {
    return -1;
  }
}

 static void Main(string[] args)
 {
    ITest t = new Test();
    Console.WriteLine((t as Test).sub());
 }
输出 -1.

这一行

Console.WriteLine((t作为Test.sub())

将由
t
产生别名的内容强制转换为type
Test

您知道
t
可转换为
Test
,因为您为其分配了
Test
的实例

ITest t = new Test();
请注意,如果
t
的类型不能转换为
Test

t as Test
将计算为null,随后对.sub()的调用将导致NullReferenceException

虽然它很少是一个好的设计选择,但您可以做如下事情

if (t is Test)
{
   Console.WriteLine(((Test)t).sub());
}
else
{
    Console.WriteLine("t cannot be converted to type Test");
}
或者

Test myTest = t as Test;
if (myTest != null)
{
   Console.WriteLine(myTest.sub());
}
else
{
    Console.WriteLine("t cannot be converted to type Test");
}
这条线

Console.WriteLine((t作为Test.sub())

将由
t
产生别名的内容强制转换为type
Test

您知道
t
可转换为
Test
,因为您为其分配了
Test
的实例

ITest t = new Test();
请注意,如果
t
的类型不能转换为
Test

t as Test
将计算为null,随后对.sub()的调用将导致NullReferenceException

虽然它很少是一个好的设计选择,但您可以做如下事情

if (t is Test)
{
   Console.WriteLine(((Test)t).sub());
}
else
{
    Console.WriteLine("t cannot be converted to type Test");
}
或者

Test myTest = t as Test;
if (myTest != null)
{
   Console.WriteLine(myTest.sub());
}
else
{
    Console.WriteLine("t cannot be converted to type Test");
}

您正在从测试类调用
sub()
方法,因此,您将得到
-1
的结果。请指定问题的示例代码,以及您计划接收的内容。

您正在从测试类调用
sub()
方法,因此,您将得到
-1
的结果。请指定您遇到的问题的示例代码,以及您计划接收的内容。

因为
t
实际上是
Test
类的一个实例。将其存储到接口中并不局限于接口方法(如果用作接口,则“是”,键入到
测试,然后键入“否”。
类似示例:

IEnumerable<string> list = new List<string>();
list.Add("MyName"); // --> This won't compile since IEnumerable does not have Add method
(list as List<string>).Add("MyName"); // --> This will compile and execute, since underlying Type actually IS List<string>
IEnumerable list=new list();
列表。添加(“MyName”);/>由于IEnumerable没有Add方法,因此无法编译
(以列表形式列出)。添加(“MyName”);//-->这将编译并执行,因为底层类型实际上是List
但是很多时候,当我们使用接口时,我们不知道实际的底层类型,所以这就是为什么这种类型的转换不那么常见的原因。我想这也被认为是坏习惯,但我不确定。
正如埃里克所指出的,我们不应该制作这样的铸件。这意味着我们的设计有一个问题,我们应该考虑重新设计。

,因为<代码> t>代码>实际上是<代码>测试< /代码>类的一个实例。将其存储到接口中并不局限于接口方法(如果用作接口,则“是”,键入到

测试,然后键入“否”。
类似示例:

IEnumerable<string> list = new List<string>();
list.Add("MyName"); // --> This won't compile since IEnumerable does not have Add method
(list as List<string>).Add("MyName"); // --> This will compile and execute, since underlying Type actually IS List<string>
IEnumerable list=new list();
列表。添加(“MyName”);/>由于IEnumerable没有Add方法,因此无法编译
(以列表形式列出)。添加(“MyName”);//-->这将编译并执行,因为底层类型实际上是List
但是很多时候,当我们使用接口时,我们不知道实际的底层类型,所以这就是为什么这种类型的转换不那么常见的原因。我想这也被认为是坏习惯,但我不确定。
正如埃里克所指出的,我们不应该制作这样的铸件。这意味着我们的设计有一个问题,我们应该考虑重新设计。

这是因为铸造<代码>(t作为测试)< /代码>?这就是你想知道的吗?请注意,你的示例没有显示类之间的父/子(基/派生)关系-因此,虽然答案相同,但代码与标题不匹配。这不是一个不合理的初学者问题,我认为没有必要进行下推投票。OP创建了一个最小的程序来演示他不理解的行为。@EricJ.-你的意思是OP需要这样的东西?@AlexeiLevenkov:假设他意识到他可以用答案中的基类替换问题中的接口。这是一个初学者的问题,所以不确定这个跳跃对于这个特殊的OP来说是否太多。这是因为施法
(t作为测试)
?这就是你想知道的吗?请注意,你的示例没有显示类之间的父/子(基/派生)关系-因此,虽然答案相同,但代码与标题不匹配。这不是一个不合理的初学者问题,我认为没有必要进行下推投票。OP创建了一个最小的程序来演示他不理解的行为。@EricJ.-你的意思是OP需要这样的东西?@AlexeiLevenkov:假设他意识到他可以用答案中的基类替换问题中的接口。这是一个初学者的问题,所以不确定这个跳跃对于这个特定的操作来说是否太多。通常在使用接口时,我们不应该关心底层类型。这通常是我们有设计问题的一个线索。是的,我的意思是,只是用一些尴尬的词写了出来。我会编辑这篇文章。通常在使用界面时,我们不应该关心底层类型。这通常是我们有设计问题的一个线索。是的,我的意思是,只是用一些尴尬的词写了出来。我会编辑这篇文章。