使用C#"命名参数"的实际原因

Nic*_*las 0 c# parameters methods arguments optional-parameters

我发现C#的这个功能"命名参数"真的很奇怪,因为我看到了它的两个缺陷.该书说"命名参数赋予你"以任何顺序传递参数的能力".

我认为这个C#功能存在两个缺陷:

  1. 它违反了计算机科学中的"信息隐藏".(即:使用该方法的最终用户需要知道参数名称和数据类型才能使用该功能.)来自Java背景,这很奇怪.为什么要将参数名称暴露给用户的末尾?

  2. 它容易产生歧义,可能导致错误.(当程序员编写使用相同方法名称(也称为重载方法)的方法时,程序员需要进行额外的思考和问题.当你有两个同名的方法时,你总会得到一个"调用是不明确的"即使另一个方法具有不同数据类型的额外参数,彼此具有相同的参数.我能想到的唯一修复是使数据类型成为"强制参数",也就是没有默认值的参数,因此编译器会不要混淆.但是这个修复只是一个导致另一个最坏情况的绷带解决方案(见下文)

业内人士甚至在今天都使用这个概念吗?如果是这样,为什么要打破这两条规则"在调用方法时以任何顺序传递参数的能力"?

TLDR:通过引入可能的最坏情况场景(编译器选择了错误的方法调用......尽管两种方法相似)来清楚地说明我所说的内容:

namespace ConsoleApplication1
{
    class Venusaur
    {
        static void Main(string[] args)
        {

            new Venusaur().optMethod(fourth: "s");
        }

        public void optMethod(  string third , string fourth =  "hello", int fifth = 23, string two = "w")
        {
            // what if I wanted this method to run instead of the method below me
            Console.WriteLine("did not execute");
        }


        public void optMethod(string third = "Byte", string fourth = "hello",  int fifth = 4)
        {
            // But this method ran instead
            Console.WriteLine("run");

        }


    }
}
Run Code Online (Sandbox Code Playgroud)

ang*_*son 7

命名参数是为了使与COM(和类似技术)的互操作性更容易而添加的另一项技术.

使用该方法使用COM打开Word文档:

Document Open(
    [In] ref object FileName, 
    [In, Optional] ref object ConfirmConversions, 
    [In, Optional] ref object ReadOnly, 
    [In, Optional] ref object AddToRecentFiles, 
    [In, Optional] ref object PasswordDocument, 
    [In, Optional] ref object PasswordTemplate, 
    [In, Optional] ref object Revert, 
    [In, Optional] ref object WritePasswordDocument, 
    [In, Optional] ref object WritePasswordTemplate, 
    [In, Optional] ref object Format, 
    [In, Optional] ref object Encoding, 
    [In, Optional] ref object Visible, 
    [In, Optional] ref object OpenAndRepair, 
    [In, Optional] ref object DocumentDirection, 
    [In, Optional] ref object NoEncodingDialog, 
    [In, Optional] ref object XMLTransform
);
Run Code Online (Sandbox Code Playgroud)

它有不少于16个参数,其中15个是可选的.

如果您想指定XMLTransform参数但不关心其他参数怎么办?

您必须使用位置参数指定其余部分.使用命名参数,调用只会变为:

doc.Open("somefilename.doc", XMLTransform: xxx);
Run Code Online (Sandbox Code Playgroud)

除了dynamic一些其他的东西,它并不是一个很好的解决方案来解决很多问题,但是当你的API很大程度上依赖于包含大量参数的方法时,其中大多数都是可选的,命名参数使得感.

是的,您可以不按顺序指定参数.这并不意味着它是一个好主意或它解决了某个人真正拥有的问题.