windows C#-命名实参和可选实参(上)

通过命名实参,你可以为形参指定实参,方法是将实参与该形参的名称匹配,而不是与形参在形参列表中的位置匹配。 通过可选参数,你可以为某些形参省略实参。 这两种技术都可与方法、索引器、构造函数和委托一起使用。

使用命名参数和可选参数时,将按实参出现在实参列表(而不是形参列表)中的顺序计算这些实参。

通过命名形参和可选形参,你可以为所选形参提供实参。 此功能极大地方便了对 COM 接口(例如 Microsoft Office 自动化 API)的调用。

命名参数

有了命名实参,你将不再需要将实参的顺序与所调用方法的形参列表中的形参顺序相匹配。 每个形参的实参都可按形参名称进行指定。 例如,通过以函数定义的顺序按位置发送实参,可以调用打印订单详细信息(例如卖家姓名、订单号和产品名称)的函数。

复制代码
PrintOrderDetails("Gift Shop", 31, "Red Mug");

如果不记得形参的顺序,但却知道其名称,则可以按任意顺序发送实参。

复制代码
PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

命名实参还可以标识每个实参所表示的含义,从而改进代码的可读性。 在下面的示例方法中,sellerName 不得为 NULL 或空白符。 由于 sellerName 和 productName 都是字符串类型,所以使用命名实参而不是按位置发送实参是有意义的,可以区分这两种类型并减少代码阅读者的困惑。

当命名实参与位置实参一起使用时,只要

  1. 没有后接任何位置实参或

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");

  2. 它们用在正确位置。 在以下示例中,形参 orderNum 位于正确的位置,但未显式命名。

    PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug");

遵循任何无序命名参数的位置参数无效。

复制代码
// This generates CS1738: Named argument specifications must appear after all fixed arguments have been specified.
PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
示例

以下代码执行本节以及某些其他节中的示例。

复制代码
class NamedExample
{
    static void Main(string[] args)
    {
        // The method can be called in the normal way, by using positional arguments.
        PrintOrderDetails("Gift Shop", 31, "Red Mug");

        // Named arguments can be supplied for the parameters in any order.
        PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
        PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

        // Named arguments mixed with positional arguments are valid
        // as long as they are used in their correct position.
        PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
        PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug"); 
        PrintOrderDetails("Gift Shop", orderNum: 31, "Red Mug");

        // However, mixed arguments are invalid if used out-of-order.
        // The following statements will cause a compiler error.
        // PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
        // PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug");
        // PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop");
    }

    static void PrintOrderDetails(string sellerName, int orderNum, string productName)
    {
        if (string.IsNullOrWhiteSpace(sellerName))
        {
            throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName: nameof(sellerName));
        }

        Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}");
    }
}
COM 接口

命名实参和可选实参,以及对动态对象的支持大大提高了与 COM API(例如 Office Automation API)的互操作性。

例如,Microsoft Office Excel 的 Range 接口中的 AutoFormat 方法有七个可选形参。 这些形参如下图所示:

但是,可以通过使用命名实参和可选实参来大大简化对 AutoFormat 的调用。 如果不希望更改形参的默认值,则可以通过使用命名实参和可选实参来省略可选形参的实参。 在下面的调用中,仅为 7 个形参中的其中一个指定了值。

复制代码
var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks.Add();
excelApp.Visible = true;

var myFormat =
    Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatAccounting1;

excelApp.Range["A1", "B4"].AutoFormat( Format: myFormat );
重载决策

使用命名实参和可选实参将在以下方面对重载决策产生影响:

如果方法、索引器或构造函数的每个参数是可选的,或按名称或位置对应于调用语句中的单个自变量,且该自变量可转换为参数的类型,则方法、索引器或构造函数为执行的候选项。

如果找到多个候选项,则会将用于首选转换的重载决策规则应用于显式指定的自变量。 将忽略可选形参已省略的实参。

如果两个候选项不相上下,则会将没有可选形参的候选项作为首选项,对于这些可选形参,已在调用中为其省略了实参。 重载决策通常首选具有较少形参的候选项。

相关推荐
死磕音视频4 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲6 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
曹牧7 小时前
C#:输入的字符串格式不正确
c#
程序喵大人8 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)8 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的9 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质9 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄62310 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_9628857210 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python