Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Methods - Method parameters

C sharp



+ Font mai mare | - Font mai mic



Methods

A method is a member that implements a computation or action that can be performed by an object or class. Methods are declared using method-declarations:



method-declaration:
method-header method-body

method-header:
attributesopt method-modifiersopt return-type member-name
( formal-parameter-listopt )

method-modifiers:
method-modifier
method-modifiers method-modifier

method-modifier:
new
public
protected
internal
private
static
virtual
sealed
override
abstract
extern

return-type:
type
void

member-name:
identifier
interface-type
. identifier

method-body:
block
;

A method-declaration may include a set of attributes (17), a new modifier (10.2.2), an extern modifier (10.5.7), a valid combination of the four access modifiers (10.2.3), and a valid combination of the static (10.5.2), virtual (10.5.3), override (10.5.4), and abstract (10.5.6) modifiers. In addition, a method that includes the override modifier may also include the sealed modifier (10.5.5).

The static, virtual, override, and abstract modifiers are mutually exclusive except in one case. The abstract and override modifiers may be used together so that an abstract method can override a virtual one.

The return-type of a method declaration specifies the type of the value computed and returned by the method. The return-type is void if the method does not return a value.

The member-name specifies the name of the method. Unless the method is an explicit interface member implementation (13.4.1), the member-name is simply an identifier. For an explicit interface member implementation, the member-name consists of an interface-type followed by a "." and an identifier.

The optional formal-parameter-list specifies the parameters of the method (10.5.1).

The return-type and each of the types referenced in the formal-parameter-list of a method must be at least as accessible as the method itself (3.5.4).

For abstract and extern methods, the method-body consists simply of a semicolon. For all other methods, the method-body consists of a block which specifies the statements to execute when the method is invoked.

The name and the formal parameter list of a method define the signature (3.6) of the method. Specifically, the signature of a method consists of its name and the number, modifiers, and types of its formal parameters. The return type is not part of a method's signature, nor are the names of the formal parameters.

The name of a method must differ from the names of all other non-methods declared in the same class. In addition, the signature of a method must differ from the signatures of all other methods declared in the same class.

Method parameters

The parameters of a method, if any, are declared by the method's formal-parameter-list.

formal-parameter-list:
fixed-parameters
fixed-parameters
, parameter-array
parameter-array

fixed-parameters:
fixed-parameter
fixed-parameters
, fixed-parameter

fixed-parameter:
attributesopt parameter-modifieropt type identifier

parameter-modifier:
ref
out

parameter-array:
attributesopt
params array-type identifier

The formal parameter list consists of one or more comma-separated parameters of which only the last may be a parameter-array.

A fixed-parameter consists of an optional set of attributes (17), an optional ref or out modifier, a type, and an identifier. Each fixed-parameter declares a parameter of the given type with the given name.

A parameter-array consists of an optional set of attributes (17), a params modifier, an array-type, and an identifier. A parameter array declares a single parameter of the given array type with the given name. The array-type of a parameter array must be a single-dimensional array type (12.1). In a method invocation, a parameter array permits either a single argument of the given array type to be specified, or it permits zero or more arguments of the array element type to be specified. Parameter arrays are further described in 10.5.1.4.

A method declaration creates a separate declaration space for parameters and local variables. Names are introduced into this declaration space by the formal parameter list of the method and by local variable declarations in the block of the method. All names in the declaration space of a method must be unique. Thus, it is an error for a parameter or local variable to have the same name as another parameter or local variable.

A method invocation (7.5.5.1) creates a copy, specific to that invocation, of the formal parameters and local variables of the method, and the argument list of the invocation assigns values or variable references to the newly created formal parameters. Within the block of a method, formal parameters can be referenced by their identifiers in simple-name expressions (7.5.2).

There are four kinds of formal parameters:

Value parameters, which are declared without any modifiers.

Reference parameters, which are declared with the ref modifier.

Output parameters, which are declared with the out modifier.

Parameter arrays, which are declared with the params modifier.

As described in 3.6, the ref and out modifiers are part of a method's signature, but the params modifier is not.

Value parameters

A parameter declared with no modifiers is a value parameter. A value parameter corresponds to a local variable that gets its initial value from the corresponding argument supplied in the method invocation.

When a formal parameter is a value parameter, the corresponding argument in a method invocation must be an expression of a type that is implicitly convertible (6.1) to the formal parameter type.

A method is permitted to assign new values to a value parameter. Such assignments only affect the local storage location represented by the value parameter-they have no effect on the actual argument given in the method invocation.

Reference parameters

A parameter declared with a ref modifier is a reference parameter. Unlike a value parameter, a reference parameter does not create a new storage location. Instead, a reference parameter represents the same storage location as the variable given as the argument in the method invocation.

When a formal parameter is a reference parameter, the corresponding argument in a method invocation must consist of the keyword ref followed by a variable-reference (5.4) of the same type as the formal parameter. A variable must be definitely assigned before it can be passed as a reference parameter.

Within a method, a reference parameter is always considered definitely assigned.

The example

class Test

static void Main() , j = ', i, j);
}
}

produces the output

i = 2, j = 1

For the invocation of Swap in Main, x represents i and y represents j. Thus, the invocation has the effect of swapping the values of i and j.

In a method that takes reference parameters it is possible for multiple names to represent the same storage location. In the example

class A

void G()
}

the invocation of F in G passes a reference to s for both a and b. Thus, for that invocation, the names s, a, and b all refer to the same storage location, and the three assignments all modify the instance field s.

Output parameters

A parameter declared with an out modifier is an output parameter. Similar to a reference parameter, an output parameter does not create a new storage location. Instead, an output parameter represents the same storage location as the variable given as the argument in the method invocation.

When a formal parameter is an output parameter, the corresponding argument in a method invocation must consist of the keyword out followed by a variable-reference (5.4) of the same type as the formal parameter. A variable need not be definitely assigned before it can be passed as an output parameter, but following an invocation where a variable was passed as an output parameter, the variable is considered definitely assigned.

Within a method, just like a local variable, an output parameter is initially considered unassigned and must be definitely assigned before its value is used.

Every output parameter of a method must be definitely assigned before the method returns.

Output parameters are typically used in methods that produce multiple return values. For example:

class Test

dir = path.Substring(0, i);
name = path.Substring(i);
}

static void Main()
}

The example produces the output:

c:WindowsSystem
hello.txt

Note that the dir and name variables can be unassigned before they are passed to SplitPath, and that they are considered definitely assigned following the call.

Parameter arrays

A parameter declared with a params modifier is a parameter array. If a formal parameter list includes a parameter array, it must be the right-most parameter in the list and it must be of a single-dimensional array type. For example, the types string[] and string[][] can be used as the type of a parameter array, but the type string[,] can not. It is not possible to combine the params modifier with the ref and out modifiers.

A parameter array permits arguments to be specified in one of two ways in a method invocation:

The argument given for a parameter array can be a single expression of a type that is implicitly convertible (6.1) to the parameter array type. In this case, the parameter array acts precisely like a value parameter.

Alternatively, the invocation can specify zero or more arguments for the parameter array, where each argument is an expression of a type that is implicitly convertible (6.1) to the element type of the parameter array. In this case, the invocation creates an instance of the parameter array type with a length corresponding to the number of arguments, initializes the elements of the array instance with the given argument values, and uses the newly created array instance as the actual argument.

Except for allowing a variable number of arguments in an invocation, a parameter array is precisely equivalent to a value parameter (10.5.1.1) of the same type.

The example

class Test
elements:', args.Length);
foreach (int i in args) Console.Write(' ', i);
Console.WriteLine();
}

static void Main() ;
F(a);
F(10, 20, 30, 40);
F();
}
}

produces the output

Array contains 3 elements: 1 2 3
Array contains 4 elements: 10 20 30 40
Array contains 0 elements:

The first invocation of F simply passes the array a as a value parameter. The second invocation of F automatically creates a four-element int[] with the given element values and passes that array instance as a value parameter. Likewise, the third invocation of F creates a zero-element int[] and passes that instance as a value parameter. The second and third invocations are precisely equivalent to writing:

F(new int[] );
F(new int[] );

When performing overload resolution, a method with a parameter array may be applicable either in its normal form or in its expanded form (7.4.2.1). The expanded form of a method is available only if the normal form of the method is not applicable and only if a method with the same signature as the expanded form is not already declared in the same type.

The example

class Test

static void F()

static void F(object a0, object a1)

static void Main()
}

produces the output

F();
F(object[]);
F(object,object);
F(object[]);
F(object[]);

In the example, two of the possible expanded forms of the method with a parameter array are already included in the class as regular methods. These expanded forms are therefore not considered when performing overload resolution, and the first and third method invocations thus select the regular methods. When a class declares a method with a parameter array, it is not uncommon to also include some of the expanded forms as regular methods. By doing so it is possible to avoid the allocation of an array instance that occurs when an expanded form of a method with a parameter array is invoked.

When the type of a parameter array is object[], a potential ambiguity arises between the normal form of the method and the expended form for a single object parameter. The reason for the ambiguity is that an object[] is itself implicitly convertible to type object. The ambiguity presents no problem, however, since it can be resolved by inserting a cast if needed.

The example

class Test

Console.WriteLine();
}

static void Main() ;
object o = a;
F(a);
F((object)a);
F(o);
F((object[])o);
}
}

produces the output

System.Int32 System.String System.Double
System.Object[]
System.Object[]
System.Int32 System.String System.Double

In the first and last invocations of F, the normal form of F is applicable because an implicit conversion exists from the argument type to the parameter type (both are of type object[]). Thus, overload resolution selects the normal form of F, and the argument is passed as a regular value parameter. In the second and third invocations, the normal form of F is not applicable because no implicit conversion exists from the argument type to the parameter type (type object cannot be implicitly converted to type object[]). However, the expanded form of F is applicable, and it is therefore selected by overload resolution. As a result, a one-element object[] is created by the invocation, and the single element of the array is initialized with the given argument value (which itself is a reference to an object[]).

Static and instance methods

When a method declaration includes a static modifier, the method is said to be a static method. When no static modifier is present, the method is said to be an instance method.

A static method does not operate on a specific instance, and it is an error to refer to this in a static method. Furthermore, it is an error for a static method to include any of the following modifiers: virtual, abstract, or override.

An instance method operates on a given instance of a class, and this instance can be accessed as this (7.5.7).

The differences between static and instance members are further discussed in 10.2.5.

Virtual methods

When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. When no virtual modifier is present, the method is said to be a non-virtual method.

It is an error for a method declaration that includes the virtual modifier to include any of the following modifiers: static, abstract, or override.

The implementation of a non-virtual method is invariant: The implementation is the same whether the method is invoked on an instance of the class in which it is declared or an instance of a derived class. In contrast, the implementation of a virtual method can be superseded by derived classes. The process of superseding the implementation of an inherited virtual method is known as overriding the method (10.5.4).

In a virtual method invocation, the run-time type of the instance for which the invocation takes place determines the actual method implementation to invoke. In a non-virtual method invocation, the compile-time type of the instance is the determining factor. In precise terms, when a method named N is invoked with an argument list A on an instance with a compile-time type C and a run-time type R (where R is either C or a class derived from C), the invocation is processed as follows:

First, overload resolution is applied to C, N, and A, to select a specific method M from the set of methods declared in and inherited by C. This is described in 7.5.5.1.

Then, if M is a non-virtual method, M is invoked.

Otherwise, M is a virtual method, and the most derived implementation of M with respect to R is invoked.

For every virtual method declared in or inherited by a class, there exists a most derived implementation of the method with respect to that class. The most derived implementation of a virtual method M with respect to a class R is determined as follows:

If R contains the introducing virtual declaration of M, then this is the most derived implementation of M.

Otherwise, if R contains an override of M, then this is the most derived implementation of M.

Otherwise, the most derived implementation of M is the same as that of the direct base class of R.

The following example illustrates the differences between virtual and non-virtual methods:

class A

public virtual void G()
}

class B: A

public override void G()
}

class Test

}

In the example, A introduces a non-virtual method F and a virtual method G. The class B introduces a new non-virtual method F, thus hiding the inherited F, and also overrides the inherited method G. The example produces the output:

A.F
B.F
B.G
B.G

Notice that the statement a.G() invokes B.G, not A.G. This is because the run-time type of the instance (which is B), not the compile-time type of the instance (which is A), determines the actual method implementation to invoke.

Because methods are allowed to hide inherited methods, it is possible for a class to contain several virtual methods with the same signature. This does not present an ambiguity problem, since all but the most derived method are hidden. In the example

class A

}

class B: A

}

class C: B

}

class D: C

}

class Test

}

the C and D classes contain two virtual methods with the same signature: The one introduced by A and the one introduced by C. The method introduced by C hides the method inherited from A. Thus, the override declaration in D overrides the method introduced by C, and it is not possible for D to override the method introduced by A. The example produces the output:

B.F
B.F
D.F
D.F

Note that it is possible to invoke the hidden virtual method by accessing an instance of D through a less derived type in which the method is not hidden.

Override methods

When an instance method declaration includes an override modifier, the method is said to be an override method. An override method overrides an inherited virtual method with the same signature. Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of the method.

It is an error for an override method declaration to include any of the following modifiers: new, static, or virtual. An override method declaration may include the abstract modifier. This enables a virtual method to be overridden by an abstract method.

The method overridden by an override declaration is known as the overridden base method. For an override method M declared in a class C, the overridden base method is determined by examining each base class of C, starting with the direct base class of C and continuing with each successive direct base class, until an accessible method with the same signature as M is located. For the purposes of locating the overridden base method, a method is considered accessible if it is public, if it is protected, if it is protected internal, or if it is internal and declared in the same program as C.

A compile-time error occurs unless all of the following are true for an override declaration:

An overridden base method can be located as described above.

The overridden base method is a virtual, abstract, or override method. In other words, the overridden base method cannot be static or non-virtual.

The overridden base method is not a sealed method.

The override declaration and the overridden base method have the same declared accessibility. In other words, an override declaration cannot change the accessibility of the virtual method.

An override declaration can access the overridden base method using a base-access (7.5.8). In the example

class A
{
int x;

public virtual void PrintFields() {
Console.WriteLine('x = ', x);
}
}

class B: A
{
int y;

public override void PrintFields() {
base.PrintFields();
Console.WriteLine('y = ', y);
}
}

the base.PrintFields() invocation in B invokes the PrintFields method declared in A. A base-access disables the virtual invocation mechanism and simply treats the base method as a non-virtual method. Had the invocation in B been written ((A)this).PrintFields(), it would recursively invoke the PrintFields method declared in B, not the one declared in A, since PrintFields is virtual and the run-time type of ((A)this) is B.

Only by including an override modifier can a method override another method. In all other cases, a method with the same signature as an inherited method simply hides the inherited method. In the example

class A
{
public virtual void F()
}

class B: A
{
public virtual void F() // Warning, hiding inherited F()
}

the F method in B does not include an override modifier and therefore does not override the F method in A. Rather, the F method in B hides the method in A, and a warning is reported because the declaration does not include a new modifier.

In the example

class A
{
public virtual void F()
}

class B: A
{
new private void F() // Hides A.F within B
}

class C: B
{
public override void F() // Ok, overrides A.F
}

the F method in B hides the virtual F method inherited from A. Since the new F in B has private access, its scope only includes the class body of B and does not extend to C. The declaration of F in C is therefore permitted to override the F inherited from A.

Sealed methods

When an instance method declaration includes a sealed modifier, the method is said to be a sealed method. A sealed method overrides an inherited virtual method with the same signature.

An override method can also be marked with the sealed modifier. Use of this modifier prevents a derived class from further overriding the method. The sealed modifier can only be used in combination with the override modifier.

The example

class A

public virtual void G()
}

class B: A

override public void G()
}

class C: B

}

the class B provides two override methods: an F method that has the sealed modifier and a G method that does not. B's use of the sealed modifier prevents C from further overriding F.

Abstract methods

When an instance method declaration includes an abstract modifier, the method is said to be an abstract method. Although an abstract method is implicitly also a virtual method, it cannot have the virtual modifier.

An abstract method declaration introduces a new virtual method but does not provide an implementation of the method. Instead, non-abstract derived classes are required to provide their own implementation by overriding the method. Because an abstract method provides no actual implementation, the method-body of an abstract method simply consists of a semicolon.

Abstract method declarations are only permitted in abstract classes (10.1.1.1).

It is an error for an abstract method declaration to include the static or extern modifiers.

In the example

public abstract class Shape

public class Ellipse: Shape

}

public class Box: Shape

}

the Shape class defines the abstract notion of a geometrical shape object that can paint itself. The Paint method is abstract because there is no meaningful default implementation. The Ellipse and Box classes are concrete Shape implementations. Because these classes are non-abstract, they are required to override the Paint method and provide an actual implementation.

It is an error for a base-access (7.5.8) to reference an abstract method. In the example

class A

class B: A

}

an error is reported for the base.F() invocation because it references an abstract method.

An abstract method declaration is permitted to override a virtual method. This allows an abstract class to force re-implementation of the method in derived classes, and makes the original implementation of the method unavailable. In the example

class A

}

abstract class B: A

class C: B

}

class A declares a virtual method, class B overrides this method with an abstract method, and class C overrides the abstract method to provide its own implementation.

External methods

When a method declaration includes an extern modifier, the method is said to be an external method. External methods are implemented externally, using a language other than C#. Because an external method declaration provides no actual implementation, the method-body of an external method simply consists of a semicolon.

The extern modifier is typically used in conjunction with a DllImport attribute (B.8), allowing external methods to be implemented by DLLs (Dynamic Link Libraries). The execution environment may support other mechanisms whereby implementations of external methods can be provided.

It is an error for an external method declaration to also include the abstract modifier. When an external method includes a DllImport attribute, the method declaration must also include a static modifier.

This example demonstrates the use of the extern modifier and the DllImport attribute:

class Path

Method body

The method-body of a method declaration consists of either a block or a semicolon.

Abstract and external method declarations do not provide a method implementation, so their method bodies simply consist of a semicolon. For any other method, the method body is a block (8.2) that contains the statements to execute when the method is invoked.

When the return type of a method is void, return statements (8.9.4) in the method body are not permitted to specify an expression. If execution of the method body of a void method completes normally (that is, control flows off the end of the method body), the method simply returns to its caller.

When the return type of a method is not void, each return statement in the method body must specify an expression of a type that is implicitly convertible to the return type. The endpoint of the method body of a value-returning method must not be reachable. In other words, in a value-returning method, control is not permitted to flow off the end of the method body.

In the example

class A
{
public int F() // Error, return value required

public int G()

public int H(bool b)
else
}
}

the value-returning F method is in error because control can flow off the end of the method body. The G and H methods are correct because all possible execution paths end in a return statement that specifies a return value.

Method overloading

The method overload resolution rules are described in 7.4.2.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1090
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved