C#Tuple/List/Generics - 有更短的方法吗?

Dan*_*yel 2 c# generics boilerplate

我编写了一个解析命令行参数的程序或算法.首先,需要指定有效的参数及其属性(标志,分隔符等).

现在,我有一个辅助函数返回:: 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 );
}
Run Code Online (Sandbox Code Playgroud)

有没有办法写这个更短?我是否必须明确地将Generics放在那里?

显然,为此创建自己的类将是一个解决方案.但是不是另一个吗?

作为参考,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)
}
Run Code Online (Sandbox Code Playgroud)

另外,有没有办法启动ListsTuples以紧凑的方式?如在List(1, 2, 3, 4)(Key, Value)代替Tuple<KeyType, ValueType>(Key, Value)

此致,
Danyel.

Eri*_*sch 7

您可以使用typedef来清理代码.从技术上讲,C#没有typedef,但您可以使用using来模拟它们.像这样的东西:

using MyTuple = Tuple<Tuple<Argument, string>, Argument>;
using MyTuple2 = Tuple<Argument, string>;

public class MyClass {

    private MyTuple f(string e, List<Argument> valid) {
        var p = valid.Find( x => { return e.StartsWith( x.value ); } );
        if ( p == null )
           return new MyTuple( null, null );
        if ( p.flag )
           return new MyTuple( new MyTuple2( p, "" ), null );
        if ( p.separator.Equals(" ") && p.value.Length == e.Length )
            return new MyTuple( null, p );
        var si = e.IndexOf(p.separator);
        if ( si != p.value.Length )
            return MyTuple( null, null );
        return new MyTuple( new MyTuple2( p, 
            e.Substring( si + p.separator.Length ) ), null );
    }
}
Run Code Online (Sandbox Code Playgroud)

关于初始化的问题,我不确定我理解.元组已经有一个紧凑的初始化方法,使用构造函数参数.

列表可以使用初始值设定项,如下所示:

var s = new List<string> { "one", "two", "three" };
Run Code Online (Sandbox Code Playgroud)