命名参数何时有用?
在C#代码中是否存在位置参数不足的情况? 我真的没有看到命名参数的任何好处,相反我可以看到过度使用命名参数会使代码难以阅读? 所以我的问题是,为什么有人会使用它们,它们如何帮助编写更好的代码,因为我确信它们没有理由没有实现?
这看起来更干净:
private void Foo(1, true);
然后:
private void Foo(bar: 1, baz: true);
命名参数旨在提高可读性。 例如,我刚刚使用了一个
public void MarkAsDone(bool skipped) {}
现在通过调用没有名称的方法,我们有一个歧义
MarkAsDone(true); //does true mean that it is successfully done?
可以通过使用名称澄清来解决
MarkAsDone(skipped: true);
我认为使用命名参数会使客户端代码变得不那么模糊。
它是一个部分,当有多个具有相同类型的可选参数时,它们可用于唯一地标识可选参数
MarkAsDone(int first, int second=0, int third=0) {} /// MarkAsDone(1, third: 3);
我使用命名参数使呼叫站点更清晰,当我有默认值的参数时。 已经在许多不同的答案中讨论了默认值的情况,所以我们来谈谈呼叫站点的清晰度。
使用metasyntactic变量进行分析并不会突出其有用性。 考虑一下,如果你愿意的话,这更像是“现实世界”。
我们来看一个呼叫网站:
something.OpenFile(documentPath, true);
这是怎么回事? 它将打开documentPath
。 还有别的吗? 还有什么? 我不记得了,即使我一周前写过OpenFile
。
以下是OpenFile
三个不同的相对现实的示例。
void OpenFile(string path, bool shouldOverwrite) void OpenFile(string path, bool preserveExisting) void OpenFile(string path, bool enableWriting)
使用命名参数,我们可以使呼叫站点清晰:
something.OpenFile(documentPath, shouldOverwrite: false);
很明显,文件不会被覆盖。
something.OpenFile(documentPath, preserveExisting: false);
很明显,如果需要,文件将被覆盖。
最后,我们有:
something.OpenFile(documentPath, enableWriting: false)
很明显,该文件只能打开阅读。
这个特定的例子可以用枚举等其他东西来解决吗? 是。 你能不能改变代码? 没有。其他人对bool参数有同样的持久仇恨吗? 编号:-)
你可以用命名参数来做吗? 是。 好的本地变量名有用吗? 极大。
当我们需要使用这样的方法时,我们发现了一个非常有趣的命名参数用法:
private void ShowPopup(FrameworkElement content, string title = "My Application", bool isDialog = true, double? width = null, double? height = null, double? offsetX = null, double? offsetY = null, bool isTransparent = false, ... etc)
几乎所有参数都是可选的。 在某些情况下,您需要将所有这些参数保留为默认值,除了一个或几个参数,例如:
PopupHelper.ShowPopup(_view, isTransparent: true);
或类似的东西。
当使用可选参数调用方法时,它们非常有用 – 实际上是隐式需要的 – 因为当您使用可选参数调用方法时,必须指定要传递的方法,否则您必须提供最后一个所需的整个列表。使用。
给出这样的方法:
public void Do(Thing thing, bool doItTwice = false, bool logResults = false, string something = null, bool makeTeaAfterwards = false)
然后,您必须使用命名参数,以避免必须指定整个列表:
Do(thing, makeTeaAfterwards: true);
而不是:
Do(thing, false, false, null, true);
后者的缺点是你必须复制默认值,这会引入错误的可能性。
我不确定,但我认为你误解了命名参数。
请参阅: http : //www.dotnetperls.com/named-parameters
基本上,当您需要将大量参数发送到方法时,它们非常有用。 使用命名参数,您可以确定要发送给方法的参数
Method1(test1: 1, ..., test20: 10);
你应该小心使用它,因为它有很大的性能缺点。
如果你有一个方法签名,如:
private void Foo(int bar, bool baz);
然后命名参数没有多大帮助,没有。
但想象一下方法签名如:
private void Foo(bool bar, int baz=0, int qux=0);
并且说你想传递baz
的默认值但是qux
的参数,那么命名参数有助于:
Foo(true, qux:1);
这些天C#支持可选参数,例如:
public void Dance(string song = "makarena", string location = "your house", string performer = "Michael", DateTime? date = null, int milliseconds = 0, Action callback = null) { ///party code }
现在你可以通过跳过一些参数(以任何顺序)来调用它:
Dance(location : "my house", date : DateTime.Now, performer : "Christina");
我测试了代码。 可悲的是,我没有看到克里斯蒂娜的性感舞蹈,因为我忘了设置毫秒参数:P(不是我的蜕皮,但是那些做API的人,为什么每天可能毫秒可选?:P)。
我的观点是,它的真正价值在于COM Interop和类似的情况。 例如,Office COM对象有一些方法,其中包含许多没有这些参数的参数(例如Word.Documents.Open )。
回答了一个被删除的类似问题,所以我会在这里发布..我认为尚未包括Com Call参数:
使用命名参数有一两个很好的理由。
1)使用Com调用/可选参数时
想象一下:
var excelApp = new Microsoft.Office.Interop.Excel.Application(); excelApp.Workbooks.Add(); excelApp.Visible = true; var myFormat = Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatAccounting1; excelApp.get_Range("A1", "B4").AutoFormat(myFormat, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
在C#3.0及更早版本中,您需要为每个参数提供参数。
但是,通过使用C#4.0中引入的命名参数和可选参数,可以大大简化对AutoFormat的调用。
excelApp.Range["A1", "B4"].AutoFormat( Format: myFormat );
2)命名参数可以创建更好/更清晰的代码
File.Copy("source.txt", "destination.txt", true);
除非您是熟悉此方法的开发人员,否则您只能猜测最后一个布尔参数的用途。 使用C#4.0命名参数,可以像这样编写代码以更清楚地表达意图:
File.Copy("source.txt", "destination.txt", overwrite: true);
3)它是shoprtenes代码
而是使用
Person person = new Person(); person.FirstName = "John"; person.LastName = "Smith"; person.DateOfBirth = new DateTime(1970, 1, 1);
你可以使用(取决于可读性偏好)
Person person = new Person() { FirstName = "John", LastName="Smith", DateOfBirth = new DateTime(1970, 1, 1)};
它们可以是一个很好的意图声明,并提高可读性,其中参数是相同类型或可以隐式转换。
例如
int Duration(d1,d2)
那是从d1到d2还是d2 – d1? Intellisense可能会告诉您参数是否具有良好的名称,或者文档是否正确且是最新的。 或者你可以查看代码……
使用多个可选参数它们甚至更有用,避免像所有可选参数一样的规则必须是最后一个,并且必须指定所有不想使用默认值的参数。 总噩梦如果由于某种原因你需要重新考虑参数列表。 你可能想要考虑简洁和简洁之间的区别。 简洁总是好的,很少简洁。
我觉得它牺牲了紧凑性以便于阅读。 假设您有一个清除一些不需要的元素的函数。 不需要的可能是:旧的,已弃用的,未使用的:
// unnamed: collection.remove(true, true, false) // named: collection.remove(old:true, deprecated:true, unused:false);
当然,还有许多其他方法可以实现这一点,从按位标志到智能感知。 但是,当用Python编程时,我使用命名的params非常分配。 当然,那里没有powershell打字,而且工具更差。