1.Optional and Named Parameters

  calls these methods can optionally not specify some of the arguments, thereby accepting the default values.

  when you call a method, you can specify arguments by using the name of their parameters.

  When you pass arguments to a method, the compiler evaluates the arguments from left to right.  

示例:

    

  

  

Rules and Guidelines

when defining a method that specifies default values for some of its parameters:

  1.can specify default values for the parameters of methods, constructor methods, parameterful properties (C# indexers)

  can specify default values for parameters that are part of a delegate definition. Then, when invoking a variable of this delegate type, you can omit the arguments and accept the default values.

  2.Parameters with default values must come after any parameters that do not have default values.That is, after you define a parameter as having a default value, then all parameters to the right of it must also have default values.  

  a params array parameter (discussed later in this chapter) must come after all parameters (including those that have default values), and the array cannot have a default value itself.

  For example, in the definition of my M method, I would get a compiler error if I removed the default value ("A") for s.

  3.Default values must be constant values known at compile time.

  This means that you can set default values for parameters of types that C# considers to be primitive types. This also includes enumerated types, and any reference type can be set to null.

  For a parameter of an arbitrary value type,you can set the default value to be an instance of the value type, with all its fields containing zeroes.You can use the default keyword or the new keyword to express this; both syntaxes produce identical Intermediate Language (IL) code.

  Examples of both syntaxes are used by my M method for setting the default value for the dt parameter and guid parameter, respectively.

  4.Be careful not to rename parameter variables because any callers who are passing arguments by parameter name will have to modify their code.

  For example, in the declaration of my M method, if I rename the dt variable to dateTime, then my third call to M in the earlier code will cause the compiler to produce the following message: error CS1739: The best overload for 'M' does not have a parameter named 'dt'.

  5.Be aware that changing a parameter’s default value is potentially dangerous if the method is called from outside the module.

  A call site embeds the default value into its call. If you later change the parameter’s default value and do not recompile the code containing the call site,then it will call your method passing the old default value.

  You might want to consider using a default value of 0/null as a sentinel to indicate default behavior;this allows you to change your default without having to recompile all the code with call sites.

  

  6.cannot set default values for parameters marked with either the ref or out keywords

  because there is no way to pass a meaningful default value for these parameters.

when calling a method by using optional or named parameters:

  1.Arguments can be passed in any order;

  however, named arguments must always appear at the end of the argument list.

  2.You can pass arguments by name to parameters that do not have default values,

  but all required arguments must be passed (by position or by name) for the compiler to compile the code

  3.C# doesn’t allow you to omit arguments between commas, as in M(1, ,DateTime.Now),because this could lead to unreadable comma-counting code.

  Pass arguments by way of their parameter name if you want to omit some arguments for parameters with default values.

  4.To pass an argument by parameter name that requires ref/out

  

C#’s optional and named parameter features are really convenient when writing C# code that interoperates with the COM object model in Microsoft Office. And, when calling a COM component, C# also allows you to omit ref/out when passing an argument by reference to simplify the coding even more. When not calling a COM component, C# requires that the out/ref keyword be applied to the argument.

The DefaultParameterValue and Optional Attributes

question:want programmers to define a method indicating which parameters are optional ,and what their default value should be in a programming language and then give programmers working in other programming languages the ability to call them.

answer:the compiler of choice must allow the caller to omit some arguments and have a way of determining what those arguments’ default values should be.

how?

  In C#, when you give a parameter a default value, the compiler internally applies the System.Runtime.InteropServices.OptionalAttribute custom attribute to the parameter, and this attribute is persisted in the resulting file’s metadata.

  In addition, the compiler applies System.Runtime.InteropServices.DefaultParameterValueAttribute to the parameter and persists this attribute in the resulting file’s metadata.

  Then, DefaultParameterValueAttribute’s constructor is passed the constant value that you specified in your source code.

  when a compiler sees that you have code calling a method that is missing some arguments,the compiler can ensure that you’ve omitted optional arguments, grab their default values out of metadata, and embed the values in the call for you automatically.

2.Implicitly Typed Local Variables

C# supports the ability to infer the type of a method’s local variable from the type of expression that is used to initialize it.

示例:

  

  using the C# var token. To determine the type of the name variable, the compiler looks at the type of the expression on the right side of the assignment operator (=).

  error CS0815: Cannot assign <null> to an implicitlytyped local variable) because null is implicitly castable to any reference type or nullable value type; therefore, the compiler cannot infer a distinct type for it.

  it is possible to initialize an implicitly typed local variable with null if you explicitly specify a type (String, in my example). Although this is possible, it is not that useful because you could also write String x = null; to get the same result.

  In the fourth assignment,Not only is this a lot of typing, but if you ever decide to change the collection type or any of the generic parameter types, then you would not have to modify your code on both sides of the assignment operator, too.

  use var to have the compiler automatically infer the type of the elements. This demonstrates that it is possible and quite useful to use var with foreach, using, and for statements. It can also be useful when experimenting with code.

C#’s implicitly typed local variable feature must be used when working with anonymous types within a method

不能使用的情况:

  1.You cannot declare a method’s parameter type by using var.

  The reason for this should be obvious to you because the compiler would have to infer the parameter’s type from the argument being passed at a callsite and there could be no call sites or many call sites

  2.you cannot declare a type’s field by using var. There are many reasons why C# has this restriction.

  One reason is that fields can be accessed by several methods and the C# team feels that this contract (the type of the variable) should be stated explicitly.

  Another reason is that allowing this would permit an anonymous type (discussed in Chapter 10) to leak outside of a single method.

var comprare with dynamic:

  Do not confuse dynamic and var.

  Declaring a local variable by using var is just a syntactical shortcut that has the compiler infer the specific data type from an expression.

  The var keyword can be used only for declaring local variables inside a method, whereas the dynamic keyword can be used for local variables, fields, and arguments.

  You cannot cast an expression to var, but you can cast an expression to dynamic.

  You must explicitly initialize a variable declared using var, whereas you do not have to initialize a variable declared with dynamic.

3.Passing Parameters by Reference to a Method

1.By default, the common language runtime (CLR) assumes that all method parameters are passed by value.

  When reference type objects are passed, the reference (or pointer) to the object is passed (by value) to the method.This means that the method can modify the object and the caller will see the change.

  For value type instances, a copy of the instance is passed to the method. This means that the method gets its own private copy of the value type and the instance in the caller isn’t affected.

  so,In a method, you must know whether each parameter passed is a reference type or a value type because the code you write to manipulate the parameter could be markedly different.

2.The CLR allows you to pass parameters by reference instead of by value.

  In C#, you do this by using the out and ref keywords. Both keywords tell the C# compiler to emit metadata indicating that this designated parameter is passed by reference

  the compiler uses this to generate code to pass the address of the parameter rather than the parameter itself.

ref and out:

  1.From the CLR’s perspective, out and ref are identical—that is, the same IL is produced regardless of which keyword you use, and the metadata is also identical except for 1 bit, which is used to record whether you specified out or ref when declaring the method.

  2.However, the C# compiler treats the two keywords differently, and the difference has to do with which method is responsible for initializing the object being referred to.

  If a method’s parameter is marked with out, the caller isn’t expected to have initialized the object prior to calling the method. The called method can’t read from the value, and the called method must write to the value before returning.

  If a method’s parameter is marked with ref, the caller must initialize the parameter’s value prior to calling the method. The called method can read from the value and/or write to the value.

  To summarize, from an IL or a CLR perspective, out and ref do exactly the same thing: they both cause a pointer to the instance to be passed. The difference is that the compiler helps ensure that your code is correct.

  3.Using out and ref with value types gives you the same behavior that you already get when passing reference types by value.

  With reference types, the caller allocates memory for a pointer to a reference object,and the callee manipulates this pointer. Because of this behavior, using out and ref with reference types is useful only when the method is going to “return” a reference to an object that it knows about.

  With value types, out and ref allow a method to manipulate a single value type instance. The caller must allocate the memory for the instance, and the callee manipulates that memory.

  4.Using out with large value types is efficient because it prevents instances of the value type’s fields from being copied when making method calls.

  5.the CLR allows you to overload methods based on their use of out and ref parameters.

  

  It’s not legal to overload methods that differ only by out and ref because the metadata representation of the method’s signature for the methods would be identical.So I couldn’t also define the following method in the preceding Point type.

  static void Add(out Point p) { ... }

  error CS0663: 'Add' cannot define overloaded methods because it differs only on ref and out.

why C# requires that a call to a method must specify out or ref?

  After all, the compiler knows whether the method being called requires out or ref and should be able to compile the code correctly. It turns out that the compiler can indeed do the right thing automatically.

  However, the designers of the C# language felt that the caller should explicitly state its intention. This way, at the call site, it’s obvious that the method being called is expected to change the value of the variable being passed.

示例1:ref、out的区别

  

  The address of x is then passed to GetVal. GetVal’s v is a pointer to the Int32 value in Main’s stack frame. Inside GetVal, the Int32 that v points to is changed to 10

  

  Inside AddVal,the Int32 that v points to is required to have a value already. So, AddVal can use the initial value in any expression it desires. AddVal can also change the value, and the new value will be “returned” to the caller.

  attempts to pass an uninitialized value to a method expecting a ref parameter produces the following message: error CS0165: Use of unassigned local variable 'x'.

示例2:引用类型优化

  

示例3:值互换

  

  

  The problem is that variables passed by reference to a method must be of the same type as declared in the method signature. In other words, Swap expects two Object references, not two String references.

  优化方式二

  

  

  For some other examples that use generics to solve this problem, see System.Threading’s Interlocked class with its CompareExchange and Exchange methods. 

示例四:传参匹配问题

  

  won’t compile,because the parameters passed must match the parameters expected by the method is to ensure that type safety is preserved.

4.Passing a Variable Number of Arguments to a Method

convenient

how to achieve?

  the params keyword  tells the compiler to apply an instance of the System.ParamArrayAttribute custom attribute to the parameter.

  效果等同于

  no Add method is defined that takes five Int32-compatible arguments;

  however, the compiler sees that the source code has a call to Add that is being passed a list of Int32 values and that there is an Add method whose array-of-Int32 parameter is marked with the ParamArray attribute.

  So the compiler considers this a match and generates code that coerces the parameters into an Int32 array and then calls the Add method.

  The end result is that you can write the code, easily passing a bunch of parameters to Add, but the compiler generates code as though you’d written the first version that explicitly constructs and initializes the array.

compiler?

  When the C# compiler detects a call to a method.

  the compiler checks all of the methods with the specified name, where no parameter has the ParamArray attribute applied. If a method exists that can accept the call, the compiler generates the code necessary to call the method.

   However, if the compiler can’t find a match, it looks for methods that have a ParamArray attribute to see whether the call can be satisfied.

   If the compiler finds a match, it emits code that constructs an array and populates its elements before emitting the code that calls the selected method.

limites?

  1.Only the last parameter to a method can be marked with the params keyword (ParamArrayAttribute).

  2.This parameter must also identify a single-dimension array of any type.

  3.It’s legal to pass null or a reference to an array of 0 entries as the last parameter to the method.

  4.you can write a method that takes an arbitrary number of parameters where the parameters could be any type.

  5.Be aware that calling a method that takes a variable number of arguments incurs an additional performance hit unless you explicitly pass null.To help reduce the performance hit associated with this, you may want to consider defining a few overloaded methods that do not use the params keyword 

  After all, an array object must be allocated on the heap, the array’s elements must be initialized, and the array’s memory must ultimately be garbage collected.

  

  the Concat method defines several overloads that do not use the params keyword. These versions of the Concat method are the most frequently called overloads, and these overloads exist in order to improve performance for the most common scenarios. The overloads that use the params keyword are there for the less common scenarios; these scenarios will suffer a performance hit, but fortunately, they are rare.

5.Parameter and Return Type Guidelines

1.When declaring a method’s parameter types, you should specify the weakest type possible, preferring interfaces over base classes.

because it is much more flexible and can be used in a much wider range of scenarios.

2.declare a method’s return type by using the strongest type possible (trying not to commit yourself to a specific type).

but,when you want let the caller have as much flexibility as possible when calling a method, allowing the method to be used in the widest range of scenarios.in which you want to leave yourself some flexibility to change what your method returns, choose a weaker return type.

Notice in this example that I’m using the strongest of the weakest types. For instance, I’m not using an IEnumerable<String> or even ICollection<String>.

6.Const-ness

why the CLR does not support constant objects/arguments?

  In some languages, such as unmanaged C++, it is possible to declare methods or parameters as a constantthat forbids the code in an instance method from changing any of the object’s fields or preventsthe code from modifying any of the objects passed into the method.

  1.in unmanaged C++, marking an instance method or parameter as const ensured only that the programmer could not write normal code that would modify the object or parameter.

  Inside the method, it was always possible to write code that could mutate the object/parameter by either casting away the const-ness or by getting the address of the object/argument and then writing to the address

  In a sense, unmanaged C++ lied to programmers, making them believe that their constant objects/arguments couldn’t be written to even though they could.

  2.When designing a type’s implementation, the developer can just avoid writing code that manipulates the object/arguments.

  For example, strings are immutable because the String class doesn’t offer any methods that can change a string object.

   3.it would be very difficult for Microsoft to endow the CLR with the ability to verify that a constant object/argument isn’t being mutated.

  The CLR would have to verify at each write that the write was not occurring to a constant object, and this would hurt performance significantly

  4.constant support adds a lot of complexity for developers.

  For example, if a type is immutable, all derived types would have to respect this.

  In addition, an immutable type would probably have to consist of fields that are also of immutable types.

9.Parameters的更多相关文章

  1. ORA-01078: failure in processing system parameters & LRM-00109: could not open parameter file

    安装了Oracle 12C后,启动数据库的过程中出现如下错误 SQL> startup ORA-01078: failure in processing system parameters LR ...

  2. Unity: Passing Constructor Parameters to Resolve

    In this tutorial we will go through of couple different ways of using custom constructor parameters ...

  3. C#编程:SqlCommand.Parameters.Add()方法的参数问题。

    在存储过程中添加2个参数 sql语句 例: “update [tablename] username = @username where id=@id” 然后把需要的 command.Paramete ...

  4. Parameter index out of range (2 > number of parameters, which is 1)

    今天在实现一个功能时遇到一个问题,解决了很久.结果是#{}与${}使用错误的原因.但是具体原因还不是很清楚,写此篇总结,知道的可以交流. 具体描述为:通过教师的头衔(1高级讲师2首席讲师)及名称进行模 ...

  5. java中获取接口(方法)中的参数名字(eclipse设置编译参数)(java8 javac -parameters)

    interface接口参数 jdk1.7及以前使用spring功能实现的: 注意: 1.该功能只能获取类的方法的参数名,不能获取接口的方法的参数名. public static void test() ...

  6. ios AFNetworking 3.0 报错 : *** Assertion failure in -[AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:],

    AFNetWorking[:] *** Assertion failure -- :::] *** Terminating app due to uncaught exception 'NSInter ...

  7. Parameter Passing / Request Parameters in JSF 2.0 (转)

    This Blog is a compilation of various methods of passing Request Parameters in JSF (2.0 +) (1)  f:vi ...

  8. How to Change RabbitMQ Queue Parameters in Production?

    RabbitMQ does not allow re-declaring a queue with different values of parameters such as durability, ...

  9. has no parameters and arguments were supplied

    这个问题,让Insus.NET花上不少时间与心机. 在项目中,Insus.NET是使用这个逻辑组件: <程序与数据库之间的连接桥梁和逻辑处理>http://www.cnblogs.com/ ...

  10. ES6函数剩余参数(Rest Parameters)

    我们知道JS函数内部有个arguments对象,可以拿到全部实参.现在ES6给我们带来了一个新的对象,可以拿到除开始参数外的参数,即剩余参数(废话好多 O(∩_∩)O~). 这个新的对象和argume ...

随机推荐

  1. 什么是BI(Business Intelligence)【转】

    谈谈对BI的理解,从BI的定义.基本技术.专业名词.实例应用及扩展等方面进行重新描述,巩固对BI的理解. 一.BI的定义 BI是Business Intelligence的英文缩写,中文解释为商务智能 ...

  2. javascript 深拷贝

    javascript存在两种拷贝:浅拷贝.深拷贝. 它们最大的区别在于引用类型的拷贝上:浅拷贝复制的是引用(指针),深拷贝复制的是里面的数据. 由于以上原因,在下例中 浅拷贝修改的值影响了声明的对象a ...

  3. 利用Qt Assistant 定制帮助文档

    为了将Qt Assistant定制为自己应用程序的帮助文档浏览器.需要完成以下几步: 一.导入HTML格式的帮助文档 (1)首先,针对自己的应用程序创建HTML格式的帮助文档,请参见<Doxyg ...

  4. linux设备驱动归纳总结(三):6.poll和sellct【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-61749.html linux设备驱动归纳总结(三):6.poll和sellct xxxxxxxxxx ...

  5. PayPal网站付款标准版(for PHP)

    简单整理一下PHP项目整合PayPal支付功能. 一.表单的构建: <form method="post" name="form" action=&quo ...

  6. SQLServer学习笔记<>相关子查询及复杂查询

    二.查询缺少值的查询 在这里我们加入要查询2008年每一天的订单有多少?首先我们可以查询下订单表的订单日期在2008年的所有订单信息. 1 select distinct orderdate,coun ...

  7. postgresql之ctid的浅谈

       ctid: 表示数据记录的物理行当信息,指的是 一条记录位于哪个数据块的哪个位移上面. 跟oracle中伪列 rowid 的意义一样的:只是形式不一样.    例如这有个一表test:查看每行记 ...

  8. 20145227 《Java程序设计》实验五实验报告

    20145227 <Java程序设计>实验五实验报告 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验过程 1.先运行TCP代码,一人服务 ...

  9. 天大acm 题号1002 Maya Calendar

    Description 上周末,M.A. Ya教授对古老的玛雅有了一个重大发现.从一个古老的节绳(玛雅人用于记事的工具)中,教授发现玛雅人使用了一个一年有365天的叫做Haab的历法.这 个Haab历 ...

  10. c# UDP通信 列子

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...