接口实例

San*_*eep 6 .net c# interface

我是C#.net的新手,很惊讶地知道可以创建一个接口的实例

Iinterface myDimensions = (Iinterface) myBox;
Run Code Online (Sandbox Code Playgroud)

如何为这种类型的语句分配内存?是在堆上分配内存吗?

任何人都可以给出使用这种类型的实例化的任何情况.

实现接口的类可以显式实现该接口的成员.显式实现成员时,不能通过类实例访问它,而只能通过接口的实例访问它.

为什么在语言中强制执行这样的约束?

谢谢,

Eri*_*ert 13

在回答您的第一个问题之前,我注意到您在这里有两个问题.在将来,当您有两个问题时,请考虑在Stack Overflow上提出两个单独的问题.您可能已经注意到,当您在一个问题中提出两个问题时,几乎每个人都会忽略第二个问题.

我很惊讶地知道可以像创建接口的实例一样

Iinterface myDimensions = (Iinterface) myBox; 
Run Code Online (Sandbox Code Playgroud)

如何为这种类型的语句分配内存?是在堆上分配内存吗?

正如其他人所指出的,这不一定是创建实现接口的类型实例.每个人似乎已经忘记了他们急于告诉你引用转换不分配内存,拳击转换确实分配内存.如果myBox是结构类型,那么这将在堆上为"包装器"分配内存,并在包装​​器中复制该值.然后包装器实现接口.

继续你的第二个问题:

实现接口的类可以显式实现该接口的成员.显式实现成员时,不能通过类实例访问它,而只能通过接口的实例访问它.为什么在语言中强制执行这样的约束?

显式接口实现的目的是使类能够实现特定接口,而不要求这些方法出现在不需要的地方.例如,假设你有:

class MyConnection : IDisposable
{
    public void OpenConnnection() { ... }
    public void CloseConnection() { ... }
    public void Dispose() { ... CloseConnection(); ... }
}
Run Code Online (Sandbox Code Playgroud)

如果处理开放连接与关闭连接相同,那么您可能不希望通过以下两种方法混淆用户:(1)使用两种方法执行相同操作,或者(2)使用方法OpenConnection与非显而易见性配对像Dispose这样的名字.通过使Dispose"隐藏",除非将对象转换为IDisposable,然后让用户更容易发现正确的事情.

您使用此方法的另一种情况是,当您有两个具有相同名称的接口时:

interface IFoo { void M(); }
interface IBar { void M(); }
Run Code Online (Sandbox Code Playgroud)

现在,如何创建一个实现IFoo和IBar的C类,但是对于这两个M方法有不同的实现?如果您需要两个不同的实体,则必须对其中一个或两个使用显式实现.


Ben*_*n M 10

那不是实例化 - 它是一个类型转换.该实例是原始对象,即myBox.至于内存,是的,为引用分配了内存 - 无论是在堆上还是堆栈完全取决于上下文.在你的例子中(看起来像是在函数中),我猜是堆栈.

关于显式实现:语言特性允许单个类实现包含具有完全相同签名的一个或多个成员的两个或更多个接口.例如:

interface A
{
   void Foo();
}

interface B
{
   void Foo();
}

class C : A, B
{
   void A.Foo()
   {
   }

   void B.Foo()
   {
   }
}
Run Code Online (Sandbox Code Playgroud)

没有这个功能,编译器不清楚哪个接口成员C.Foo实现了.当然,需要注意的是,调用者不能简单地调用C.Foo,因为调用哪种方法也不明显; C因此,必须首先将类型的对象强制转换为A或者B使程序员的Foo-lish意图明确.


Jus*_*ner 7

你拥有的是一个演员,而不是一个实例.在这种情况下,必须在其他地方创建对象:

// Allocate memory on the stack to point to the location on the heap
// to store the object and create the object on the heap.
Box box = new Box();

// Allocate memory on the stack to point to the location on the heap
// and point it to the already existing object on the heap.
IInterface iBox = (IInterface)box;
Run Code Online (Sandbox Code Playgroud)

您从MSDN引用的引用是对显式接口实现的引用.这些可能有点令人困惑.一个简单的例子是最简单的:

public interface ISomething
{
    void SayHi();
}

public class Something : ISomething
{
    public void SayHi() { Console.WriteLine("Hello World!"); }

    public void ISomething.SayHi() { Console.WriteLine("42!"); }
}
Run Code Online (Sandbox Code Playgroud)

现在您的代码可以具有以下内容:

Something obj = new Something();

// Outputs "Hello World!"
obj.SayHi();

ISomething iObj = obj;

// Outputs "42!"
iObj.SayHi();
Run Code Online (Sandbox Code Playgroud)

在那个例子中,内存的工作方式与我最初解释的相同.