C# 接口变量无法访问所有类方法

C# 接口变量无法访问所有类方法,c#,asp.net,.net,C#,Asp.net,.net,我有一个接口和一个类,如下所示: interface ILastName { string LastName(); } class MyName:ILastName { public string FirstName() { return "Michael"; } public string LastName() { re

我有一个接口和一个类,如下所示:

interface ILastName
    {
        string LastName();
    }
    class MyName:ILastName
    {
        public string FirstName()
        {
            return "Michael";
        }
        public string LastName()
        {
            return "Dutt";
        }
    }
现在请参见我的以下问题和假设
(一)

在上面的代码行中,
newmyname()
帮助创建类的对象,并在堆中分配内存,这意味着
Myname
的所有方法都存在于堆中以供访问。并且
myNameObj
包含对该内存的引用,这意味着我们可以使用
myNameObj
访问所有方法。(方法名称)

但是
(二)

在上面的一行中,同样的事情发生了
newmyname()
创建类n的对象在heap中占用内存,这意味着heap中可以访问的所有方法

但我们只能访问接口中存在的那些方法,请参见下面我可以访问的行

obj.LastName(); 
但下面是不可能的为什么

obj.FirstName();    

为什么??obj还保存着堆中
MyName
类获取的内存引用,与
myNameObj
相同,因此我们无法访问接口中不存在的方法?

这是因为变量
obj
被键入
ILastName

因此,
ILastName
中的所有属性、方法等都是可见的。它们在那里,但您需要将其强制转换为正确的类型才能访问它们

如果您尝试此方法,它会起作用:

MyName obj = new MyName();
这也会起作用:

var obj = new MyName();

编译时类型和运行时类型之间存在差异。obj的运行时类型是MyName,而编译时类型是ILastName。 如果我做了下面的事情呢

class MySecondName:ILastName
{
    public string SecondName()
    {
        return "Michael";
    }
    public string LastName()
    {
        return "Dutt";
    }
}

ILastName obj;
int i = new Random().Next() % 2;
if (i == 0) obj = new MyName();
else obj = new MySecondName();
无法判断obj的类型。已知的只是它是一个ILastName,因此已知它唯一的方法是LastName()


即使只有一种可能的类型,如您的示例中所示,编译器也不会查看该类型。它只考虑编译时类型。

只有接口ILastName中的内容可用于obj(ILastName obj=new MyName();)用法。接口只知道方法(string LastName();),因此只能访问接口中的内容

MyName myNameObj=新的MyName();是MyName类中的对象,因此它能够访问MyName中的所有方法和变量

MyName:ILastName显示MyName是来自ILastName接口的类实现,因此它必须实现ILastName中的所有方法

MyName myNameObj=新的MyName();ILastName obj=newmyname(); 创建对象,从而为其分配内存


希望我的解释有助于您的理解。

因为您声明了
obj
,通过它访问实例的变量为
ILastName
。如果要访问
FirstName()
方法,则需要将
obj
强制转换为
MyName
,例如:
((MyName)obj).FirstName()
,但并非所有
ILastName
都是
MyName
。这是编译时间限制。如果您强制转换它,它将工作。同意您的意见,我认为它将在和类型和对象之间创建映射。ILastName中存在的方法是什么?它将映射到MyName类,当我们编写MyName MyName=new MyName()时,它将MyName类中存在的所有方法映射到MyName。乐趣:将obj声明为动态的,并调用obj.FirstName()。你只会有50%的时间出现异常。
var obj = new MyName();
class MySecondName:ILastName
{
    public string SecondName()
    {
        return "Michael";
    }
    public string LastName()
    {
        return "Dutt";
    }
}

ILastName obj;
int i = new Random().Next() % 2;
if (i == 0) obj = new MyName();
else obj = new MySecondName();