【发布时间】:2013-02-04 23:28:06
【问题描述】:
我编写了一个解析命令行参数的程序或算法。首先,需要指定有效参数及其属性(标志、分隔符等)。
现在,我有一个帮助函数,它返回:Tuple<Tuple<Argument, String>, String>:元组中的第一个元素(也是一个元组)包含一个“键值对”,null 如果找不到对。第二个元素包含一个被标识为选项的字符串,分隔符为" "(意味着该值将是命令行中的下一个元素)
该函数的代码如下:
private Tuple<Tuple<Argument, String>, Argument> f(string e, List<Argument> valid) {
var p = valid.Find( x => { return e.StartsWith( x.value ); } );
if ( p == null )
return new Tuple<Tuple<Argument, String>, Argument>( null, null );
if ( p.flag )
return new Tuple<Tuple<Argument, String>, Argument>( new Tuple<Argument, String>( p, "" ), null );
if ( p.separator.Equals(" ") && p.value.Length == e.Length )
return new Tuple<Tuple<Argument, String>, Argument>( null, p );
var si = e.IndexOf(p.separator);
if ( si != p.value.Length )
return new Tuple<Tuple<Argument, String>, Argument>( null, null );
return new Tuple<Tuple<Argument, String>, Argument>( new Tuple<Argument, String>( p, e.Substring( si + p.separator.Length ) ), null );
}
有什么办法可以写得更短吗?我必须明确将泛型放在那里吗?
显然,为此创建自己的类是一种解决方案。但不是还有一个吗?
作为参考,Scala 中的相同代码如下所示:
val po = valid.find(p => e.startsWith(p.value))
po match {
case Some(p) =>
if ( p.flag )
(Some((p, "")), None)
else if ( p.separator.matches(" |\t") && p.value.length == e.length )
(None, Some(p))
else {
val si = e.indexOf(p.separator)
if ( si != p.value.length )
(None, None)
else
(Some((p, e.substring(si + p.separator.length))), None)
}
case _ => (None, None)
}
另外,有没有办法以紧凑的方式启动Lists 或Tuples?如List(1, 2, 3, 4) 或(Key, Value) 而不是Tuple<KeyType, ValueType>(Key, Value)
问候,
丹尼尔。
【问题讨论】:
-
为什么是嵌套元组?为什么不使用三元素元组?
Tuple<Argument,String, Argument>? -
我几乎从不使用元组。自定义类或匿名类型可以让您的代码在 99% 的时间里更简洁、更短。
-
没有真正的原因,除了使用三元素元组它对于代码实际在做什么是不透明的。前两个元素形成键值对的三元素元组不是很清楚,因此嵌套元组。
-
我的问题是我无法理解您在这里晦涩难懂的意图。否则我也许可以帮助你。 我的意思是:请发布一个命令行示例以及您想用它实现什么。
-
不能更同意@HighCore。有时使用元组对一系列思路进行原型设计很好,但是一旦您开始看到这种讨厌的东西 (
Tuple<Tuple<Argument, String>, Argument>),您可能应该考虑另一种策略。
标签: c# generics boilerplate