C # interface

xiaoxiao2021-04-11  1.6K+

The first section

Interface (interface) is used to define an agreement of a program. The class or structure of the interface should be strictly consistent with the definition of the interface. With this agreement, you can leave the restrictions on the programming language (theoretical). The interface can be inherited from multiple base interfaces, and the class or structure can implement multiple interfaces. The interface can contain methods, attributes, events, and indexers. The interface itself does not provide the implementation of the members it defined. The interface only specifies the membership that implements the interface or interface that the interface must be provided.

The interface is like a template. This template defines how objects must be implemented. The purpose is to let these methods can be referenced as an interface instance. The interface cannot be instantiated. Classs can implement multiple interfaces and are indexed by these implementations. Interface variables can only index instances of classes that implement the interface. example:

Interface iMyexample {string this [int index] {get; set;} EventHandler Even; vide; string point {get; set;}} public delegate Void EventHandler (Object Sender, Event E);

The interface in the above example contains an index this, an event Even, a method Find and a property Point.

The interface can support multiple inheritance. As in the following example, the interface "ICOMBOBOX" inherits from "ITextBox" and "IListbox".

interface IControl {void Paint ();} interface ITextBox: IControl {void SetText (string text);} interface IListBox: IControl {void SetItems (string [] items);} interface IComboBox: ITextBox, IListBox {}

Class and structure can instantiate the interface. As in the following example, class "editbox" inherits class "Control" while inheriting from "iDatabase" and "icontrol".

Interface Idatabase (Binder B); PUBLIC CLASS Editbox: Control, Icontrol, Idatabase; PUBLIC VOID (Binder B) {...}}

In the above code, the "Paint" method comes from the "iControl" interface; "Bind" method is implemented from the "iDatabase" interface and implemented in the "editbox" class as "PUBLIC".


1, the interface in the C # is defined independently of the class. This is aligned with the C model, and the interface in C is actually an abstract base class.

2, interfaces and classes can inherit multiple interfaces.

3. Category can inherit a base class, the interface does not inherit the class. This model avoids the multi-inheritance problem of C , and the implementation in different base classes in C may conflict. Therefore, this kind of complex mechanism such as virtual inheritance and explicit scope is also no longer needed. The simplified interface model of the C # helps speed up the development of the application.

4. An interface defines a reference type with abstract members. One of the interfaces in C # actually does only exist of a method mark, but there is no code at all. This suggests that you cannot instantiate an interface, you can only instantiate an object derived from the interface.

5, the interface can define methods, attributes, and indexes. Therefore, compare a class, the particularity of the interface is: When defining a class, you can derive from multiple interfaces, and you can only derive from only one class. Interface and components

The interface describes the service provided by the component. Interacting between components and components, components and customers are interacting through an interface. Therefore, once the component is released, it can only provide reasonable, consistent service by pre-defined interfaces. The stability between this interface definition allows the customer to apply developers to construct a rugged application. A component can implement multiple component interfaces, and a particular component interface can also be implemented by multiple components.

The component interface must be self-description. This means that the component interface should not depend on the specific implementation, and the implementation and interface isolation completely eliminates the coupling relationship between the user and the implementation of the interface, enhances the level of information. At the same time, this also requires the component interface to use a language that is unrelated to the component. The description criterion of the current component interface is the IDL language.

Since the interface is the protocol between components, once the interface of the assembly is released, the component producers should keep the interface as constant as possible, any changes to interface grammar or semantic changes, can cause existing components and customers. The relationship is destroyed.

Each component is autonomous, with its unique features, can only communicate with external interfaces. When a component needs to provide a new service, you can implement it by adding a new interface. Will not affect the customer already existing in the original interface. And new customers can reselect new interfaces to get services.

Componentization programming

Componentized programming methods inherit and developed object-oriented programming methods. It applies object technology to the system design, making further abstractions for the implementation of the programming of the object. We can use the components to design the components as a method of constructing the system's architecture level, and the components can be easily implemented using object-oriented methods.

Component programming emphasizes the true software reusability and height interoperability. It focuses on the generation and assembly of the components, which together constitute the core of the component manufacturing program design. The process of components is not only the needs of the application system, but the component market itself has also promoted the development of components and promoted the exchange and cooperation of software vendors. The assembly assembly allows the software product to rapidly establish a method similar to a wood, which can not only shorten the development cycle of software products, but also improve the stability and reliability of the system.

The method of component programming has the following features:

1. Programming language and independence of the development environment;

2. Transparency of the component position;

3, the process transparency of the component;

4, expandability;

5, reusability;

6, with strong infrastructure;

7. Public services at the system level;

C # language is very suitable for component programming due to its many advantages. But this is not to say that C # is a component programming language, nor does it say that C # provides components programming tools. We have repeatedly pointed out that components should have characteristics that are independent of programming language. Readers should remember this: Component model is a norm, no matter what program language design component, this specification must be observed. For example, an example of assembling a computer, as long as the various manufacturers provide us with the accessories specifications, the interface meets the unified standards, these accessories can be combined to work together, and the component programming is the same. We just say that the component programming will bring us more convenient to use the C # language.

I know what is the interface, and then how to define the interface, please see the next section - define the interface.

Second section definition interface

Technically, the interface is a set of data structures containing the function type method. With this set of data structures, customer code can call the functionality of the component object.

The general form of defining the interface is:

[attributes] [Modifiers] Interface Identifier [: Base-list] {interface-body} [;]


1, Attributes: Additional definition information.

2, Modifiers: Allows the modifiers that are used with NEW and four access modifiers. They are: New, Public, Protected, Internal, Private. In an interface definition, the same modifier does not allow multiple times, the New modifier can only appear in the nested interface, indicating that the same name member of the inheritance comes. The public, protected, both, and private modifiers define access to the interface. 3, indicators and events.

4, Identifier: Interface name.

5, base-list: Contains a list of one or more explicit base ports, and the interface is separated by a comma.

6, Interface-Body: Definition of the interface member.

7, the interface can be a member of the namespace or class, and can include the signature of the following members: method, attribute, indexer.

8, one interface can be inherited from one or more base ports.

The concept is very similar in C # and Java. The keywords for the interface are Interface, and an interface can extends one or more other interfaces. According to the practice, the name of the interface starts with uppercase letters "i". The following code is an example of a C # interface, which is exactly the same as the interface in Java:

Interface ishape {void Draw ();

If you derive from two or more interfaces, the name list of the parent interface is separated by commas, as shown in the following code:

Interface inewinterface: iParent1, iParent2 {}

However, unlike Java, the interface in the C # cannot contain a domain (Field). Also note that in C #, all methods in the interface are common methods by default. In Java, the method definition can carry a public modifier (even if it is not necessary), but in C #, the method explicitly interfaces to the interface specifies that the public modifier is illegal. For example, the following C # interface will generate a compilation error.

Interface ishape {public void Draw ();

The following example defines an interface called IControl, and includes a member method PAINT:

Interface icontrol {void paint ();

In the following example, interface IINTERFACE inherits from two base ports ibase1 and ibase2:

Interface IINTERFACE: IBASE1, IBASE2 {Void method1 (); void method2 ();

The interface can be implemented by the class. The identifier of the implemented interface appears in the base list of the class. E.g:

Class Class1: ifce1, IFACE2 {// Class member. }

When the class list is included, the base class is first appeared when the base class and the interface are included. E.g:

Class Classa: BaseClass, IFACE1, IFACE2 {// Class member. }

The following code segment defines the interface ifce, it only has one method:

Interface ifce {void showmyface ();

You cannot instantiate an object from this definition, but you can derive a class from it. Therefore, this class must implement the ShowmyFace abstract method:

Class CFace: ifce {public void showmyface () {Console.writeline ("IMPLEMentation");}}

An interface can be inherited from zero or multiple interfaces, those explicit base connectors called this interface. When an interface is more than zero-multi-expirant base, then in the form of the interface is in the form of the interface identifier, the interface identifier is followed by a colon ":" and a comma "," separated base interface identifier list. Interface base:

: Interface Type List Description:

1. The explicit base reference of an interface must be at least accessible to the interface itself. For example, specifying a private or internal interface in the base interface of a common interface is wrong.

2, one interface is inherited directly or indirectly is wrong.

3. The base reference of the interface is an explicit base interface and is the base reference thereof. In other words, the set of basegings is completely composed of explicit base interfaces and their explicit base interfaces. In the example below

interface IControl {void Paint ();} interface ITextBox: IControl {void SetText (string text);} interface IListBox: IControl {void SetItems (string [] items);} interface IComboBox: ITextBox, IListBox {}

ICOMBOBOX basegings are iControl, ITextBox, and IListbox.

4. One interface inherits all members of its base connection. In other words, the above interface ICOMBOBOX inherits the member setText and SetItems as Paint.

5. A class or structure that implements an interface also implies the base interface of all interfaces.

Interface main body

An interface interface body defines a member of the interface.

Interface-body: {interface-member-declarationsopt}

The definition interface is primarily defined as a member, please see the next section - Define the interface member.

Section III Defining Interface Members

The interface can contain one and multiple members, which can be methods, attributes, index indicators, and events, but cannot be constant, domain, operator, constructor or destructuring function, and cannot contain any static members. Interface Defines Creating a new definition space and interface definitions directly included interface member definitions introduce new members into the definition space.


1. Members of the interface are members from the base interface and the members defined by the interface itself.

2. Interface definitions can define zero or more members. The member of the interface must be a method, attribute, event, or an indexer. The interface cannot contain constants, fields, operators, instance constructor, destructuring functions, or types, nor can no static members of any kind.

3. Define an interface that contains one: method, attribute, event, and indexer for each possible group.

4. Interface members' default access method is public. Interface member definitions cannot contain any modifiers, such as the member definitions that cannot be added to Abstract, Public, Protected, Internal, Private, Virtual, Override, or Static modifiers.

5. The members of the interface cannot be mutually known. The successful member does not need to be defined, but the interface can define members of the same name as inherited, then we say that the interface member covers the inherited member, but the compiler will give one caveat. Closing a warning prompt is to add a new key before the member definition. However, if there is no member in the parent interface, use the new keyword to cause the compiler to warn.

6. The name of the method must be different from all attributes and events defined in the same interface. In addition, the signature of the method must be different from the signature of all other methods defined in the same interface.

7, the name of the property or event must be different from the names of all other members defined in the same interface.

8, a signature of an indexer must be different from the signature of all other indexes defined in the same interface.

9. Attributes in the interface method declaration, the return type, the Identifier, and the form of formal-parameter-lis and the same meaning in the method declaration of a class. . An interface method declaration does not allow designation of a method main body, and the declaration usually ends with a semicolon. 10. The visitor of the interface attribute declaration corresponds to the visitor of the class attribute declared, in addition to the visitor, usually must use a semicolon. Therefore, regardless of the attribute is read or written, only written or only written, the visitor is fully determined.

11. Attributes, Types, and Form-Parameter-Lists in the interface index declaration have the same meaning as those index declarations of the class.

The interface ImyTest contains an index indicator, event E, method F, attribute P:

Interface IMYTEST {String this [int index] {get; set;} event even; void f (int value); string p {get; set;}} public delegate Void EventHandler (Object Sender, Eventargs E);

The interface istringlist in the following example contains interfaces for each possible type of member: a method, an attribute, an event, and an index.

Public Delegate Void StringListevent (istringlist sender); public interface istringlist {void add (string s); int count {get;} event stringlistevent change; string this [int index] {get; set;}}

The full name of the interface member

Full Qualified Name can also be used using interface members. The full name of the interface is constituted. The interface name plus small dots "." Retraway, such as the following two interfaces:

Interface icontrol {void Paint ();} interface itextbox: icontrol {void gettext (string text);}

Where Paint's full name is iControl.Paint, the full name of GetText is ITextBox. GetText. Of course, the name of the member in the full name must be defined in the interface, such as use iTextBox.paint. Is unreasonable.

If the interface is a member of the namespace, the full name must also contain the name of the namespace.

Namespace system {public interface iDataTable {Object Clone ();}}

Then the full name of the Clone method is system. IDATATABLE.CLONE.

Define the interface, how to access the interface, please see the next section - Access interface

Section IV, access interface

Access to the interface member

The invocation of the interface method is also the same as the rules accessed by the index indicator. If the base member is named, the underlying member will cover the high-level members of the same name. However, because the interface supports more inheritance, in the multi-inheritance, if the two parent interfaces contain members of the same name, this produces an erriness (this is also one of the reasons for the multi-inheritance mechanism of classes in C #). Explicit definitions are required:

using System; interface ISequence {int Count {get; set;}} interface IRing {void Count (int i);} interface IRingSequence: ISequence, IRing {} class CTest {void Test (IRingSequence rs) {//rs.Count ( 1); Error, count has an amphibian //rs.count = 1; error, count has an unisowed (ISEQUENCE) RS) .count = 1; // correct ((ign) rs) .count (1) ; / / Conduct the top two statements}}, the first two statements RS .count (1) and rs .count = 1 generate erlies, resulting in errors when compiling, so it must be explicitly given RS Assign the parent interface type, this assignment does not bring additional overhead at runtime.

Look at the example below:

Using system; interface integer {void add (int i);} interface idouble {void add (double d);} interface inumr: Iinteger, idouble {} class cmytest {void test (inumber num) {// Num.Add (1 ); Error Num.Add (1.0); // correct (integer) n) .Add (1); // correct (iDouble) n) .add (1); // correct}}

Call Num.Add (1) will result in an amphony because the parameter type of the candidate is applicable. However, call Num.Add (1.0) is allowed because 1.0 is inconsistent with the parameter type of floating point number parameter type and method Iinteger.Add (), and only iDouble.Add is applicable. However, as long as the explicit assignment will never produce.

The problem of multiple inheritance of the interface also brings a problem with members visiting. E.g:

Interface ibase {void fway (INT i);} interface ion ibase {new void fway (int i);} interface iright: ibase {void g ();} interface idherive: ingft, ratface {} class ctest {void test IDerived d) {d. Fway (1); // Call Ileft. Fway (ibase) D). Fway (1); // Call IBase. Fway ((ileft) d). Fway (1); // call Ileft. Fway ((iright) d). Fway (1); // Call IBASE. Fway}}

In the above example, IBASE.FWAY covered with the member method of Ileft in the derived interface ILEFT. So the call to d. Fway (1) is actually called. Although from IBase-> IRIGHT-> iDerived inheritance path, the ileft.fway method is not covered. We only need to remember this: Once the member is overwritten, all the access to its access is overwritten "intercepted".

Class implementation of the interface

As we have said, the interface definition does not include the implementation of the method. The interface can be implemented by a class or structure. We mainly tell the interface to implement the interface. When using a class to implement an interface, the name of the interface must be included in the list of base class in class definition.

The following example gives an example of an interface by a class. Where ISEQUENCE is a queue interface, it provides member methods add () add (), iRing to a recurring table interface to the queue, providing the method INSERT (Object Obj) inserted into the ring, and the method returns to the inserted position. Class RingsQuence implements interface ISEQUENCE and interface Iring. using System; interface ISequence {object Add ();} interface ISequence {object Add ();} interface IRing {int Insert (object obj);} class RingSequence: ISequence, IRing {public object Add () {...} public int Insert (Object obj) {...}}

If the class implements an interface, the class also implicit all parent interfaces of the interface, regardless of whether these parent interfaces are listed in the base class table defined by the class definition. Look at the example below:

using System; interface IControl {void Paint ();} interface ITextBox: IControl {void SetText (string text);} interface IListBox: IControl {void SetItems (string [] items);} interface IComboBox: ITextBox, IListBox {}

Here, interface ICOMBOBOX inherits ITextBox and IListbox. Class TextBox not only implements interface ITextbox, but also implements the parent interface Icontrol of interface ITextBox.

We have seen before, a class can implement multiple interfaces. Look at the example below:

Interface Idatabase (Binder B); PUBLIC CLASS Editbox: Control, Icontrol, Idatabase; PUBLIC VOID (Binder B) {...}}

Class Editbox derived from class Control and implemented Icontrol and Idatabase. In the previous example, the PAINT method in the interface iControl and the BIND method in the iDatabase interface are implemented in public members in class Editbox. C # provides an alternative way to implement these methods, which can be made to the act of performing these members into public. Interface members can be implemented with a valid name. For example, class editbox can be implemented by the method Icontrol.Paint and iDatabase. Bind.

Public class editbox: icontrol, iDatabase {void icontrol.paint () {...} void iDatabasend.bind (binder b) {...}}

Since each member is implemented by an external assignment interface member, the member implemented by this method is referred to as an external interface member. External interface members can only be called by an interface. For example, the implementation of Editbox in the PAINT method can be called only by creating an IControl interface.

Class test {static void main () {editbox editbox = new editbox (); editbox.paint (); // error: editbox does not have a Paint event icontrol control = editbox; control.paint (); // Call EditBox Paint Event} }

In the above, class Editbox inherits from the Control class and implements the Icontrol and Idatabase interface. The PAINT method in Editbox comes from the icontrol interface, and the BIND method comes from the iDatabase interface, both of which are implemented as public members in the Editbox class. Of course, we can also choose to implement interfaces as public members in C #. If each member clearly points out the implemented interface, the interface implemented by this way we call the explicit interface member (Explicit Interface Member). Use this way we rewrite the above example:

Public class editbox: icontrol, iDatabase {void icontrol.paint () {...} void iDatabasend.bind (binder b) {...}}

Explicit interface members can only call through interfaces. E.g:

Class ctest {static void main () {editbox editbox = new editbox (); editbox.paint (); // error: different ways icontrol control = editbox; control.paint (); // Call Editbox's Paint Method}}

The call to editbox.paint () in the above code is wrong because the EditBox itself does not provide this method. Control.paint () is the correct call mode.

Note: The interface itself does not provide the implementation of the defined member, which only illustrates these members, which must rely on the support of the interface or other interfaces that implement the interface.

Know how to access the interface, we also know how to implement the interface, to implement the C # interface, please see the next section - Implement the interface

Section 5, implement interface

1. Explicitly realize interface members

In order to implement the interface, the class can define an explicit interface member executor (Explicit Interface Member Implementations). Explicit Interface Members can be a method, an attribute, an event or a definition of an index indicator, defining the consistency of the full name corresponding to the member.

using System; interface ICloneable {object Clone ();} interface IComparable {int CompareTo (object other);} class ListEntry: ICloneable, IComparable {object ICloneable.Clone () {...} int IComparable.CompareTo (object other) {...} }

In the above code, iCloneable.clone and IComparable.Compareto are explicit interface member executives.


1. You cannot access the explicit interface member executter by the full name of the explicit interface in the method call, attribute access, and index indicator access. In fact, the explicit interface member executive can only be accessed by reference to an instance of the interface.

2. Explicit Interface Members cannot use any access restrictions, or add Abstract, Virtual, Override or Static modifiers.

3, explicit interface member executives and other members have different ways. The explicit interface member executor is private in a sense because it cannot be accessed through the full name of the name, and the index indicator access. But they can also be accessed by an instance of the interface, but also have a certain public property.

4. Only class is in defined, write the interface name in the base class list, and the full name, type, and return type defined in the class are exactly the same as the explicit interface member executive, the explicit interface member executive It is effective, for example:

Class Shape: iCloneable.clone () {...} int icomparable.Compareto (Object Other) {...}} There are usually two purposes using explicit interface members: 1. Because explicit interface member executives cannot pass The instance of the class is accessed, which can separate from the implementation portion of the interface from the public interface. If a class is only used inside, the user does not directly use the interface, and this explicit interface member executive can play a role.

2. The explicit interface member executive avoids confusion between interface members because of the same name. If a class wants to use different implementations of interface members with the same name and return type, this must be used to use the explicit interface member executive. If there is no explicit interface member executive, the class is not implemented for the interface members of the name and return type.

The following definition is invalid, because the interface iComparable is displayed in the base class list when the Shape definition.

Class Shape: Icloneable {Object iCloneable.clone () {...}} Class Ellipse: Shape {Object IcloneAble.clone () {...}}

Defining icloneable.clone in Ellipse is incorrect because Ellipse is implicitly implemented interface iCloneable, iCloneable still does not explicitly appear in the list of Ellipse defined base clauses.

The full name of the interface member must correspond to the members defined in the interface. As in the following example, the Paint's explicit interface member actuator must be written into icontrol.paint.

using System; interface IControl {void Paint ();} interface ITextBox: IControl {void SetText (string text);} class TextBox: ITextBox {void IControl.Paint () {...} void ITextBox.SetText (string text) {...} }

The class that implements the interface can explicitly implement the member of the interface. When a member is explicitly implemented, the member cannot be accessed by a class instance, and the member can only be accessed by an instance of the interface. Explicit interface implementation also allows programmers to inherit two interfaces of sharing the same member name and provide a separate implementation for each interface member.

The size of the box is simultaneously displayed in the metric unit and the inch unit in the following example. The Box class inherits the two interfaces of IenglishDimensions and IMEtricDimensions, which represent different degree balance systems. The two interfaces have the same member name Length and Width.

Program List 1 Demoninterface.cs

interface IEnglishDimensions {float Length (); float Width ();} interface IMetricDimensions {float Length (); float Width ();} class Box: IEnglishDimensions, IMetricDimensions {float lengthInches; float widthInches; public Box (float length, float width) {lengthInches = length; widthInches = width;} float IEnglishDimensions.Length () {return lengthInches;} float IEnglishDimensions.Width () {return widthInches;} float IMetricDimensions.Length () {return lengthInches * 2.54f;} float IMetricDimensions.Width () {Return WidthIns * 2.54F;} public static void main () {// Define a real class object "mybox" :: box mybox = new box (30.0F, 20.0F); // Define an interface "edimensions" :: IEnglishDimensions eDimensions = (IEnglishDimensions) myBox; IMetricDimensions mDimensions = (IMetricDimensions) myBox; // output: System.Console.WriteLine ( "Length (in): {0}", eDimensions.Length ()); System.Console. WriteLine ("Width: {0}", edimensions.width ()); System.Console.writeline ("Length (cm): {0}", mdimensions.Length ()); System.Console.wri "Width (cm): {0}", mdimensions.width ());}} Output: Length (in): 30, Width (in): 20, Length (cm): 76.2, Width (cm): 50.8

Code Discussion: If you want the default metrics to use English units, you will implement both methods of leadth and width, and explicitly implement the Length and Width methods from the iMtricDimensions interface:

public float Length () {return lengthInches;} public float Width () {return widthInches;} float IMetricDimensions.Length () {return lengthInches * 2.54f;} float IMetricDimensions.Width () {return widthInches * 2.54f;}

In this case, the English unit can be accessed from the class instance, and the metric unit is accessed from the interface instance:

System.console.writeline ("Length (in): {0}", MyBox.Length ()); System.Console.writeline ("Width: {0}", mybox.width ()); System. Console.writeline ("Length (cm): {0}, mdimensions.Length ()); System.Console.writeline (" Width (cm): {0} ", mdimensions.width ()); 2, inheritance interface Implementing the interface has no variability, but this does not mean that the interface is no longer developed. Similar to the inheritance of the class, the interface can also inherit and develop.

Note: Interface inheritance and class inheritance, first, class inheritance is not only inheritance, but also to achieve inheritance; and interface inheritance is just a manifold. That is, the derived class can inherit the method of the base class, while the derived interface only inherits the member method of the parent interface, without the implementation of the parent interface, secondly, C # Class inheritance is only allowed to inherit, but the interface inheritance Allow multiple inheritance, one sub-interface can have multiple parent interfaces.

The interface can be inherited from zero or multiple interfaces. When inheriting from multiple interfaces, use ":" to follow the inherited interface name, multiple interface names, ",". The inherited interface should be accessible, such as inheriting from a Private type or an Internal type interface, is not allowed. The interface is not allowed to inherit itself directly or indirectly. Similar to the inheritance of the class, the inheritance of the interface also forms the hierarchy between the interfaces.

Please see the example below:

using System; interface IControl {void Paint ();} interface ITextBox: IControl {void SetText (string text);} interface IListBox: IControl {void SetItems (string [] items);} interface IComboBox: ITextBox, IListBox {}

The inheritance of an interface also inherits all members of the interface, and the interface ITEXTBOX and IListbox are inherited from the interface iControl in the example, which inherits the PAINT method of the interface Icontrol. Interface ICOMBOBOX is inherited from interface ITextBox and IListbox, so it should inherit the interface ITExtBox's setText method and IListbox's setItems method, as well as Icontrol's Paint method. A class inherits all interfaces that are provided by its basic classes.

A derived class cannot be changed from the interface mapping of its basic class inheritance by explicitly implementing an interface. For example, in the declaration

Interface icontrol {void Paint ();} class control: icontrol {public void point () {...}} class textbox: control {new public void point () {...}}

The method in TextBox is hidden in Control Paint, but there is no change from the mapping from Control.Paint to Icontrol.Paint, and Paint will have the following effects through class instances and interface instances.

Control c = new control (); TextBox t = new textbox (); icontrol IC = C; icontrol it = t; c.paint (); // affects control.paint (); T.Paint (); // TextBox.paint (); IC.Paint (); // affects control.paint (); it.paint (); // affects control.paint (); however, when an interface method is mapped to a virtual in a class Method, derived class is impossible to overwrite this virtual method and changing the implementation function of the interface. For example, rewrite the above statement as

Interface icontrol {void Paint ();} class control: icontrol {public virtual void point () {...}} class text () {public override void point () {...}}

It will see the following results:

Control c = new control (); TextBox t = new textbox (); icontrol IC = C; icontrol it = t; c.paint (); // affects control.paint (); T.Paint (); // TextBox.paint (); ic.paint (); // affects control.paint (); it.paint (); // affects TextBox.paint ();

If the explicit interface member implementation procedure cannot be declared as virtual, it is impossible to overwrite an explicit interface member implementation program. An explicit interface member implementation program calls another method is effective, while the other method can be declared as virtual so that the derived class can overwrite it. E.g:

interface IControl {void Paint ();} class Control: IControl {void IControl.Paint () {PaintControl ();} protected virtual void PaintControl () {...}} class TextBox: Control {protected override void PaintControl () { ...}}

Here, the class inherited from Control can be specialized for Icontrol.Paint implementation programs by coverage method PaintControl. 3, re-implement the interface

We have already introduced that derived classes can overload the membership methods that have been defined in the base class. Similar concepts are introduced into the implementation of the class to the interface of the interface (RE-Implement). The class that inherits the interface implemented can be rectified. This interface requires that occurs in the list of class definitions. The reality of the interface must also strictly comply with the rules of the first implementation interface, and the derived interface mapping does not have any impact on interface mappings established for the empowerment of the interface.

The following code gives examples of interface reality:

Interface icontrol {void point (); class control: icontrol void icontrol.paint () {...} Class MyControl: Control, Icontrol public void Paint ()}}

In fact,: Control maps icontrol.paint to Control.icontrol.Paint, but this does not affect the reality in MyControl. In the rectification in MyControl, iControl.Paint is mapped to MyControl.Paint.

When the reality of the interface, the inherited public member definition and the definition of the explicit interface member of the explicit interface is involved in the process of interface mapping. Using system; interface iMethods {void f (); void g (); void h (); void i ();} class base: iMethods {void iMethods.f () {} void iMethods.g () {} public void H () {} public void i () {}} class derived: base, iMethods {public void f () {} void iMethods.h () {}}

Here, the implementation of the interface IMETHODS in Derived maps the interface method to derived.f, base.imethods.g, derived.imethods.h, and base.i. As we said, the class is implicitly implemented all the parent interfaces of the interface when implementing an interface. Similarly, the class is implicitly reached all parent interfaces of the interface while re-implementing an interface.

Using system; interface ibase {void f ();} interface idherid: ibase {void g ();} class c: idherived {void ibase.f () {// The code implemented to F ...} void iderived.g ( ) {// implement code ...}} class d: c, iDerived {public void f () {// Implemented code ...} public void g () {// Implemented the code ...}}

Here, the reality of iDerived also implements the reality of IBase, and maps IBASE.f to D.f. 4, mapping interface

Categories must provide specific implementations for members of all interfaces listed in the base class table. The implementation of the interface mapping is called an interface mapping.

Mapping, math representation of the corresponding functional relationship. The meaning of the interface mapping is also the same. The interface is implemented by a class, so for each member defined in the interface, a member of the class should provide a specific implementation for it.

The following conditions must be met between members of the class and the project it mapped.

1. Both A and B are members of the members, the name, type, and type reference (including the number of parameters, and the type of each parameter) should be consistent.

2. If A and B are attributes, the names of A and B should be consistent, and the accessors of A and B are also similar. However, if a is not an explicit interface member executive, a allows you to add your own accessor.

3. If A and B are time, the names of A and B, the type should be consistent.

4. If A and B are index indicators, the types A and B are type, and the number of references (including the number of parameters, and the type of each parameter) should be consistent. And the A and B accessers are also similar. However, if a is not an explicit interface member executive, a allows you to add your own accessor.

So, for an interface member, how to determine which class member is implemented? What kind of member map is an interface member map? Here, we describe the process of interface mapping. Assume that class c implements an interface IINTERFACE, Member is a member in the interface IINTERFACE, who is positioned by who the interface member MEMBER, that is, the MEMBER mapping process is like this:

1. If there is a explicit interface member actuator in C, the actuator corresponds to the interface IINTERFACE and its member MEMBER, and it implements the Member member.

2, if the condition (1) is not satisfied, and there is a non-static public member in C, which corresponds to the interface member MEMBER, which is made by Member members. 3. If the above conditions are still unsatisfactory, look for a c class d in the base class list defined by class C, with D instead of C.

4. Repeat steps 1-- 3, traverse all direct base classes and non-direct base classes of C until a member of the class satisfying the condition.

5. If you still haven't found it, the report is wrong.

Below is an example in which a base class method is invoked to implement interface members. Class Class2 implements the interface interface interface1, class class class class class class class class Class1 member also participates in the interface mapping, that is, when the class class2 is implemented when the interface interface1 is implemented, the member method F provided by the class class1 is implemented by the interface Interface1. Method F:

Interface interface1 {void f (); class class1 {public void f () {}} class class2: class1, interface1 {new public void g ()}}

Note: Members of the interface include their own definition, and include members of all parent interfaces defined by the interface. When the interface map is mapped, it is necessary to map all members of the explicitly defined defined in the interface, but also map all interface members implicitly inherited from the parent interface. Pay attention to the following two points when performing interface mapping:

1. When deciding which member of the class is implemented, the interface member in the class is prioritized than other members.

2. Members using private, protected, and static modifiers cannot participate in implementation interface mapping. E.g:

Interface iCloneable {Object Clone ();} class c: iCloneable {Object iCloneable.clone () {...} public object clone () {...}}

Examples of Members Icloneable.clone are implemented by members of Interface Icloneable, because it is an explicitly explained interface member, which has higher priority than other members.

If a class implements two or more interfaces, types, and parameter types, one member in the class may implement all of these interface members:

Interface iControl {void Paint (); interface means {void pressure ();} class page: icontrol, iForm {public void point () {...}}

Here, both interface Icontrol and IFORM methods Paint are mapped to the PAINT method in class Page. Of course, these two methods can be implemented separately by explicit interface members:

Interface icontrol {void Paint ();} interface iform {void pressure ();} class page: icontrol, iForm {public void icontrol.paint () {// specific interface implementation code} public void iform.paint () {/ / Concrete interface implementation code}}

The above two kinds of writing are correct. However, if the interface member covers the member of the parent interface in the inheritance, the implementation of the member may have to map to the explicit interface member executive. Look at the example below:

Interface ibase {Int p {get;}} interface id;} ipase {new int p ();

Interface IDerived Inherited from Interface IBase, when the member method of interface IDerived overwrites the membership method of the parent interface. Because there is a member of the same name, the implementation of the two interface members will not be able to distinguish the interface mapping. So, if a class is to implement interface IDerived, you must define at least one explicit interface member executive. Both the following writing methods are reasonable: // 1: Both the two interface members use explicit interface members to implement the LASS C: iDerived {Int ibase.p GET {// Specific interface implementation code} int idherid. P () {// Specific interface implementation code}}}} // 2: Interface members of IBASE use explicit interface members to implement Class C: IDerived {Int ibase.p get {// Specific interface implementation code} Public int P () {// Specific interface implementation code}} // 3: Interface members of IderiveD use explicit interface members to implement Class C: IDerived {public int P get {// specific interface implementation code } Intiderived.p () {// specific interface implementation code}}

Another situation is that if a class implements a plurality of interfaces, these interfaces have the same parent interface, and this parent interface is allowed to be implemented once.

using System; interface IControl {void Paint (); interface ITextBox: IControl {void SetText (string text);} interface IListBox: IControl {void SetItems (string [] items);} class ComboBox: IControl, ITextBox, IListBox {void IControl .Paint () {...} void itxtbox.settext (string text) {...} void ilistbox.setitems (String [] items) {...}}

In the above example, class ComboBox implements three interfaces: iControl, ITextBox, and IListbox. If ComboBOX not only implements the IconTrol interface, but also achieves their parent interface icontrol while implementing ITEXTBOX and IListbox. In fact, the implementation of interface ITEXTBOX and ILISTBOX, shared the implementation of the interface Icontrol.

We have a comprehensive understanding of the C # interface, basically how to apply C # interface programming, but in fact, C # is not only applied to the .NET platform, it also supports the previous COM, you can implement COM class to .NET Class conversion, such as C # calling the API. For knowledge, please see the next section - interface conversion.

Section 6, interface conversion

C # not only supports the .NET platform, but also supports the COM platform. In order to support COM and .NET, C # contains a unique language characteristic called attribute. A property is actually a C # class, which provides meta information by modifying source code. Property allows C # to support specific technologies such as COM and .NET without interfere with language specification itself. C # provides an attribute class that converts the COM interface to a C # interface. Other attribute classes convert COM classes to C # classes. Doing these conversions do not require any IDL or class factories.

Any COM components now deployed can be used in interface conversion. Normally, the required adjustment is completely automated.

In particular, you can use the runtime to call the COM component from the .NET framework. This packaging converts the COM interface provided by the COM component to an interface compatible with the .NET framework. For OLE Automation Interfaces, RCW can automatically generate from the type library; for non-OLE automation interfaces, developers can write custom RCWs, manually map the type of types provided by the COM interface to the type compatible with the .NET framework. Use the COMIMPORT COM component COM Intero to provide access to existing COM components without the need to modify the original component. Using the COMIMPORT Reference COM component often includes the following aspects:

1. Create a COM object.

2. Determine if the COM interface is implemented by an object.

3, call the method on the COM interface.

4. Implement the objects and interfaces that can be called by the COM client.

Create a COM package

To make the C # code reference COM objects and interfaces, you need to include the definition of the COM interface in C #. The easiest way to do this is to use TLBIMP.EXE (Type Library Import), which is a command line tool included in the .NET Framework SDK. TLBIMP converts the COM-type library to .NET framework metadata, effectively creates a managed package that can be called from any hosted language. The .NET Frame Metadata created with TLBIMP can be included in the C # internal version via the / r compiler option. If you use the Visual Studio development environment, you only need to add a reference to the COM-type library, which will automatically complete this conversion.

TLBIMP performs the following conversion:

1. COM COCLASS is converted to a C # class with a parameter constructor.

2. The COM structure is converted to a C # structure with a common field.

Checking a good way for TLBIMP output is to run the .NET Framework SDK command line tool ILDASM.EXE (Microsoft Intermediate Language Discharger) to view the result of the conversion.

Although TLBIMP is a preferred method for converting COM definition to C #, it is not possible to use it at any time (for example, when there is no COM defined type library or when the TLBIMP cannot process the definition in the type library, it cannot be used) . In these cases, another method is to manually define COM definitions in a C # source code using C # properties. After creating a C # source mapping, you can generate a managed package with just compiling C # source code.

The main attributes that implement COM mapping requires understanding:

1. Comimport: It lays the class as a COM class implemented outside.

2, GUID: It is used to specify a unique unique identifier (UUID) for classes or interfaces.

3, InterfaceType, which specifies that the interface is derived from IUNKNOWN or from Idispatch.

4, preservesig, which specifies whether the return value should be converted from HRESULT to the .NET framework exception. Declaring COM COCLASS

COM Coclass is represented in C # as class. These classes must have the COMIMPORT attribute associated with it. The following restrictions apply to these classes:

1. Class cannot inherit from any other class.

2, the class cannot implement any interface.

4. The class must also have a GUID property that sets the global unique identifier (GUID).

The following example declares a CoClass in C #:

// Declare a COM class FilgraphManager [COMIMPORT, GUID ("E436EBB3-524F-11CE-9F53-0020AF0BA770")] Class FilgraphManager {}

The C # compiler will add a parameter constructor that can call this constructor to create an instance of COM COCLASS.

Create a COM object

COM CoClass is represented in C # as a class with a parameter constructor. Use the New operator to create instances of this class equivalent to calling CoCreateInstance in C #. You can easily instantiate such a class: Class Mainclass {public static void main () {FILGRAPHMANAGER FILG = New FilgraphManager ();}} Declaration COM interface

The COM interface is represented in C # as an interface with the COMIMPORT and GUID properties. It cannot contain any interface in its base interface list, and must declare the interface member function in the order in which the method appears in the COM interface.

The COM interface declared in the COM interface must contain a statement of all members of its base interface, except for members of iUnknown and IDispatch (the .NET Framework will automatically add these members). The COM interface derived from idispatch must be tagged with the interface attribute. When calling the COM interface from the C # code, the public language runtime must seal the parameters and return values ​​transmitted between the COM object. There is a default type for each .NET framework type, and the public language runtime will be encapsulated when the default type is encapsulated between COM calls. For example, the default gate of the C # string value is to be encapsulated to the local type LPTSTR (pointing to a pointer to the TCHAR character buffer). You can rewrite the default encapsulation processing using the Marshalas property in the C # declaration of the COM interface.

In COM, returning a successful or failed common method is to return a HRESULT and have an OUT parameter labeled "RetVal" in the MIDL to the actual return value for the method. In the C # (and .NET framework), indicating that the standard method that has occurred has caused an exception. By default, the .NET framework provides an automatic mapping between the two exception handling types for the COM interface method thereof.

The return value is changed to the signature of the parameter marked as RetVal (if the method is not marked as RetVal, it is VOID).

The parameters labeled RetVal are peeled from the parameter list of the method.

Any non-success return value will result in trigger system.comException exception.

This example shows the COM interface declared with MIDL and the same interface with a C # declaration (note that these methods use COM error handling methods).

Below is the C # program of the interface conversion:

using System.Runtime.InteropServices; // declare a COM interface IMediaControl [Guid ( "56A868B1-0AD4-11CE-B03A-0020AF0BA770"), InterfaceType (ComInterfaceType.InterfaceIsDual)] interface IMediaControl // can not be listed here, any base interfaces {void Run (); void pause (); void stop (); void getState ([in] int mstimeout, "out] OUT INT PFS); void renderfile ([IN, MARSTYPE.BSTR)] string strfilename); Void AddSourceFilter ([In, MarshalAs (UnmanagedType.BStr)] string strFilename, [Out, MarshalAs (UnmanagedType.Interface)] out object ppUnk); [return: MarshalAs (UnmanagedType.Interface)] object FilterCollection (); [return: MarshalAs (UnmanagedType Interface] Object regfiltercollection (); void stopwhenready ();} To prevent HRESULT translation to comexception, attach the preservesig (true) attribute to the method in the C # declaration. Below is a program that uses COM objects using COM objects.

Program List 2 Demoncom.cs

using System; using System.Runtime.InteropServices; namespace QuartzTypeLib {// declare a COM interface IMediaControl, media player from the interface COM class [Guid ( "56A868B1-0AD4-11CE-B03A-0020AF0BA770"), InterfaceType (ComInterfaceType. InterfaceIndIndiaControl {// List the interface member void Run (); void pause (); void paystate; void getState ([in] int mstimeout, [out] OUT INT PFS); Void Renderfile ([in, MarshalAs (UnmanagedType.BStr)] string strFilename); void AddSourceFilter ([In, MarshalAs (UnmanagedType.BStr)] string strFilename, [Out, MarshalAs (UnmanagedType.Interface)] out object ppUnk); [return: MarshalAs (UnmanagedType.Interface )] object FilterCollection (); [return: MarshalAs (UnmanagedType.Interface)] object RegFilterCollection (); void StopWhenReady ();} // declare a COM class: [ComImport, Guid ( "E436EBB3-524F-11CE-9F53-0020AF0BA770 ")] Class FilgraphManager // This class can no longer inherit other base classes or interface {// There is no code here, the system automatically adds a default constructor}} Class mainclass {public static void main (String [] args {// command line parameter: if (args.length! = 1) {Displayusage (); return;} String filename = args [0]; if (f) ilename.Equals ( "/?")) {DisplayUsage (); return;} // declare a real class object FilgraphManager: QuartzTypeLib.FilgraphManager graphManager = new QuartzTypeLib.FilgraphManager (); // declare a real class object IMediaControl :: QuartzTypeLib .Imediacontrol mc = (quartztypelib.imediacontrol) graphManager; // Method for calling COM: mc.renderfile (filename); // Run file. MC.Run (); // Temporary stop. Console.writeline ("Press Enter to Continue. "); console.readline ();} private static void displayusage () {// Display console.writeline (" Media Player: Play AVI file. "); console.writeLine (" Usage: VideoPlayer.exe file Name ");}} Run example:

To display a movie sample clock.avi, use the following command:

Interop2% WINDIR% / Clock.avi

This will display the movie on the screen until you press the ENTER button. Use the Win32 API.NET Framework in the .NET Framework program to access the native code base by static DLL entry points. The DLLIMPORT property is used to specify a DLL location that contains an external method.

The DLLIMPORT attribute is defined as follows:

namespace System.Runtime.InteropServices {[AttributeUsage (AttributeTargets.Method)] public class DllImportAttribute: System.Attribute {public DllImportAttribute (string dllName) {...} public CallingConvention CallingConvention; public CharSet CharSet; public string EntryPoint; public bool ExactSpelling; Public Bool PreservesIg; Public Bool SetLastError; Public String Value {Get {...}}}}


1. DLLIMPORT can only be placed on the method statement.

2, DLLIMPORT has a single positioning parameter: specify a dllname parameter that contains the DLL name of the imported method.

3, DLLIMPORT has five named parameters:

A, the CallingConvention parameter indicates the invocation of the entry point. If you do not specify a callingconvention, use the default value CALLINGCONVENTION.WINAPI.

b, the Charset parameter indicates the character set in the entry point. If a charset is not specified, use the default value charset.Auto.

c, the entryPoint parameter gives the name of the DLL in the mouthpoint. If EntryPoint is not specified, the name of the method itself is used.

D, the exactspelling parameter indicates whether EntryPoint must match the spelling of the indicated entry point. If you do not specify EXACTSPELLING, use the default value false.

E, the signature of the preservesig parameter indication method should be retained or converted. When the signature is converted, it is converted into a signature of an additional output parameter named RETVAL with the HRESULT return value and the return value. If PRESERVESIG is not specified, use the default true true.

f, setLastError parameter indication method preserved Win32 "Previous Error". If setLastError is not specified, the default value FALSE is used.

4, it is a one-time property class.

5. In addition, the method of modifying the DLLIMPORT attribute must have an extern modifier.

Below is an example of C # calling the win32 messagebox function:

Using system; using system.Runtime.InteropServices; class mainapp {// uses the dllimport reference USER32.DLL class. MessageBox class from user32.dll [DllImport ( "user32.dll", EntryPoint = "MessageBox")] public static extern int MessageBox (int hWnd, String strMessage, String strCaption, uint uiType); public static void Main () {MessageBox (0, "Hello, this is pinvoke!", ".NET", 0);}}

Object-oriented programming languages ​​have almost all of this concept, and abstract classes provide greater flexibility for realizing abstract things. C # is no exception, C # deepens the application of abstract classes by covering the technique of virtual interface. For the knowledge of this, please see the next section - cover the virtual interface

Section 7, cover the virtual interface

Sometimes we need to express an abstract thing, it is a summary of something, but we can't really see that it has become an entity in front of us, and has an abstract class for this object-oriented programming language. C # As an object-oriented language, it will inevitably introduce an abstract class. Interfaces and abstract classes allow you to create a definition of component interactions. Through the interface, you can specify the method you must implement, but do not actually specify how to implement the method. Abstract classes allow you to create behavior definitions and provide some public implementations for inherited classes. Tools that implement polymorphisms, interfaces, and abstract classes in components.

An abstract class must provide all members of the interface listed in the basic class list. However, an abstract class is allowed to map the interface method into the abstraction method. E.g

Interface iMethods {void f (); void g ();} Abstract Class C: IMETHODS {public abstract void f (); public abstract void g ();

Here, iMethods's implementation function maps F and G to the abstract method, they must be overwritten in non-abstract classes from C. Note that the explicit interface member implementation function cannot be abstract, but the explicit interface member implementation function can of course call the abstraction method. E.g

Interface iMethods {void f (); void g ();} Abstract Class C: iMethods {void iMethods.f () {ff ();} void iMethods.g ()} void iMethods.g () {gg ();} protected Protected abstract void gg ();

Here, the non-abstract class derived from C is to cover the FF and GG, so an actual implementation of IMETHODS is provided.


New Post(0)