www.188bet .comC#命令行解析工具

以前天WR发布了vs17,vs17得使用C#7.0,在此前,我写起一致篇博客,关于C#7.0,参见:http://lindexi.oschina.io/lindexi/post/C-7.0/

自将喻我们少单主意去取C#输入的指令执行参数。

不过WR砍了有的意义,添加了有意义。

<!–more–>

乃我重新勾一首,关于C# 7.0

率先只点子:

<!– 下面说的C#
7.0功能将在未来发布,首先需要安装Visual
Studio 15 Preview
4,听说这个版本安装很快。
–>

林选臣大神写的,他的法门好粗略。

C# 7.0 可以当 VS 17
使用,这多少个本我下载公司版及传百度云,有亟待可以到小说最后去[下载](#VS
17 下载)。

第一复制两独八九不离十至路

本文紧要:C# 7.0 带来的新力量

      public class CommandLineArgumentParser
    {
        private readonly List<CommandLineArgument> _arguments;

        public CommandLineArgumentParser(string[] args)
        {
            _arguments = new List<CommandLineArgument>();

            for (var i = 0; i < args.Length; i++)
            {
                _arguments.Add(new CommandLineArgument(_arguments, i, args[i]));
            }
        }

        public static CommandLineArgumentParser Parse(string[] args)
        {
            return new CommandLineArgumentParser(args);
        }

        public CommandLineArgument Get(string argumentName)
        {
            return _arguments.FirstOrDefault(p => p == argumentName);
        }

        public IEnumerable<CommandLineArgument> GetEnumerator()
        {
            foreach (var temp in _arguments)
            {
                yield return temp;
            }
        }

        public bool Has(string argumentName)
        {
            return _arguments.Count(p => p == argumentName) > 0;
        }
    }

    public class CommandLineArgument
    {
        private readonly List<CommandLineArgument> _arguments;

        private readonly string _argumentText;

        private readonly int _index;

        internal CommandLineArgument(List<CommandLineArgument> args, int index, string argument)
        {
            _arguments = args;
            _index = index;
            _argumentText = argument;
        }

        public CommandLineArgument Next
        {
            get
            {
                if (_index < _arguments.Count - 1)
                {
                    return _arguments[_index + 1];
                }

                return null;
            }
        }

        public CommandLineArgument Previous
        {
            get
            {
                if (_index > 0)
                {
                    return _arguments[_index - 1];
                }

                return null;
            }
        }

        public CommandLineArgument Take()
        {
            return Next;
        }

        public IEnumerable<CommandLineArgument> Take(int count)
        {
            var list = new List<CommandLineArgument>();
            var parent = this;
            for (var i = 0; i < count; i++)
            {
                var next = parent.Next;
                if (next == null)
                    break;

                list.Add(next);

                parent = next;
            }

            return list;
        }

        public static implicit operator string(CommandLineArgument argument)
        {
            return argument?._argumentText;
        }

        public override string ToString()
        {
            return _argumentText;
        }
    }
  • out 重临值定义

  • Tuples

  • 格局匹配

  • ref 重临本地值

  • 其中函数

  • www.188bet .com,举地点得支撑辣么大

  • throw 表达式

  • 广义异步再次回到路

  • 数值常量语法

接下来于主函数

<!–more–>

    var arguments = CommandLineArgumentParser.Parse(args);

C# 7.0的效益首假如多少处理,让代码更简单,让代码性能更强

如果要

叫代码简单是自家认为无苟6.0,性能WR为了Iot做的。C#速度差,垃圾wr就让C#足直接看内存,让速度变快,这么些下边没有说

次个措施要动用 Nuget

C# 7.0 最好的凡 使用 Tuple
。即使事先也暴发,可是现在版本相比好用。实际抄袭了某脚本。

  Install-Package CommandLineParser

<!–
比较大修改是可以使用Tuples
来多个返回,其实是抄袭了某脚本
–> <!–
多返回这个在之前也有做,他这样就是小改。
–>

下一场形容一个工具类,代码是在申龙斌大神博客
抄的

修改万分的发出 Case 。形式匹配,能够判明项目,其实这么些动用是咱来类
a,类b、c继承a,这时用就于好,怎么着使在下边会说。

   class Options

   {

        // 短参数名称,长参数名称,是否是可选参数,默认值,帮助文本等

        // 第一个参数-d

        [Option("d", "dir", Required = true, HelpText = "PGN Directory to read.")]

        public string PgnDir { get; set; }

        // 第二个参数-s

        [Option("s", "step", DefaultValue = 30, HelpText = "The maximum steps in PGN game to process.")]

        public int MaxStep { get; set; }



        [HelpOption]

        public string GetUsage()

        {

            // 应该可以根据前面的参数设置自动生成使用说明的,这里没有使用

            var usage = new StringBuilder();

            usage.AppendLine("OpeningBook 1.0");

            usage.AppendLine("-d PgnDir [-s MaxSteps=30]");

            return usage.ToString();

        }

}

假若觉得这么些意义没有用,能够去 Visual studio 按反馈喷

主程序Main里使用

<!–
如果觉得这个和我一样觉得没用,可以去Visual
studio 按反馈喷 –>

var options = new Options();

if (Parser.Default.ParseArguments(args, options))

{

     string pgnDir = options.PgnDir;

     int maxStep = options.MaxStep;

     // 参数取出来了,可以随便使用了

     // 本例中参数比较简单,稍微有点大材小用了

}

else  
{
//转化失败

      Console.WriteLine(options.GetUsage());

}

若是好奇他是怎么入手,能够翻https://github.com/dotnet/roslyn

争以参见:http://www.cnblogs.com/speeding/archive/2012/08/07/2626066.html

out 重返值定义

大家原先只要采用out 总是要在外定义大家变量。

第一定义一个 变量,使用函数,那样看需要差不多写代码

  public void PrintCoordinates(Point p)
  {
    int x, y; // 在外面定义
    p.GetCoordinates(out x, out y);
    WriteLine($"({x}, {y})");
  }

当7.0大家得动用在out定义大家变量,这样看起不是在一个区域,可是可削减自身之代码

public void PrintCoordinates(Point p)
{
    p.GetCoordinates(out int x, out int y);
    WriteLine($"({x}, {y})");
}

于out定义类型,定义可以就此var

见状就自才说这么来因而,假诺我们开没有规定大家回来的是呀,然后直接定义,需要修改地点大多,不过一旦我们应用Var就足以给我们定义修改少,一般以描绘就用事先想大家用用什么,不要老是改

万一我们拔取一个回去吗bool,那么可以{使用out的价值

public void PrintStars(string s)
{
    //转换,可以是数字,显示
    if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); }
    else { WriteLine("Cloudy - no stars tonight!"); }
}

== 下边代码被WR删了,从前来说及,现实wr没有做

使发生重临值我们不欲,可以out
*,这样大家就甭知道此重临值,原先无欲以自己还要想一个变量,然后vs说自己之没有利用,现在大家一贯就非叫他号称

每当大家下有归多单,这时不需之得据此*

public void PrintStars(string s)
{
    //转换,可以是数字,显示
    if (int.TryParse(s, out *)) { WriteLine("转换成功"); }
    else { WriteLine("转换失败"); }
}

== 下边代码WR没有做,不需要的再次来到值是可使用_

参见:http://www.cnblogs.com/linxuanchen/p/c-sharp-command-line-argument-parser.html

形式匹配

形式匹配是连 is 和 switch ,下边先说 is

C# 7.0可以行使 is 一部分替代 as

咱得看清一个价是否是一个品类,淌假若这赋值,在往日,使用的代码需要两行

    if(o is int)
    {

        int i=(int) o;
    }

尚可以采纳 as

    int? i = o as int;

唯独在新的C#,可以利用

o is int i

这就是说我们虽可一向使用i

于大家一个断定,假如我们有了object
o是int,那么大家虽然以int i=(int)o;

假使我们object不是int,那么转换object o是string,string s=(string)o;

顿时也就是是指向上面的语

int.TryParse(s,out i);

咱俩可以简化,判断是勿是int,假倘诺为i,这时便回到true

然后判断是匪是string,是就是改变,成功使用i

if (o is int i || (o is string s && int.TryParse(s, out i)) { /* use i */ }

而 is 的用法在于 switch

大家于Case能够选项目

switch(shape) 
{
    case Circle c:
        WriteLine($"circle with radius {c.Radius}");
        break;
    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} square");
        break;
    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} rectangle");
        break;
    default:
        WriteLine("<unknown shape>");
        break;
    case null:
        throw new ArgumentNullException(nameof(shape));
}

case 顺序很紧要,可以看好断定项目,可是 case 还足以勾兑判断。

                switch (item)
                {
                    default:
                        throw new InvalidOperationException("unknown item type"); 

                    case 0:
                        break;

                    case int val:
                        sum += val;
                        break;

                    case var @var when (@var != null && (int) (@var) == 45):
                        break;

                    //  The order of case clauses now matters!
                    case IEnumerable<object> subList when subList.Any():
                        sum += Sum(subList);
                        break;

                    case IEnumerable<object> subList:
                        break;

                    case null:
                        break;
                }

专注 default
在终极,即便他后边有言,除非是语句识别,那么最后谋面进行他。

http://www.cnblogs.com/speeding/archive/2012/08/07/2626066.html

Tuples

先前大家需要再次回到多单有接触难,可以使out参数,可以Tuples<string,double>

咱做了修改,可以使用新的不二法门,这样我们回来六只就可直接跟某某废品语言这重返

(string, string, string) LookupName(long id) // tuple return type
{
    ... // 返回多个数据,我们在数据拿到多个数据
    return (first, middle, last); // tuple literal
}

var names = LookupName(id);

咱这么用第一归回值:names.Item1暨原几乎没有改,这样对重回值不佳,因为大家难以去记,哪个重临值是什么

俺们只要为他一个好记的 变量,能够描绘在函数定义

(string first, string middle, string last) LookupName(long id)

我们利用第一独names.first,这样用就爱,原因是好被一个表述他是意的变量。

回去可以用return (first, middle, last);,必须同事先定义顺序一样,但要定义了名,能够下

return last:last,first:first

斯点子是异常好之,不需与概念之次第那样。

对此调用函数,可以拔取一个变量,可以运用多单变量

    (string first, string middle, string last) = LookupName(id1);
    var name = LookupName(id1);

好望个别个代码,成效一样,可是首先单代码除了选拔变量类型,同样可使
var

<!–
第一个first就是返回的第一个,我们可以使用var
,因为我们不需要定义类型
–>

    (var fist,var midd)=Lookup(id);

若大家有差不几个var,那么我们得简简单单var (first, middle, last) = LookupName(id1);概念有变量

我们不涉第二独重临值,可以选取(var first,*)=Lookup(id);

除了艺术以,可以于变量使用

                var sumNew = (first: 1, count: 20);

这般就是定义了一个,可以以他的称谓,不使
item原的,也尽管是以概念,给他变量。

地点代码的意思:可以定义一个席卷每起名称的变量,可以以行使时,用定义的变量

            var sumNew = (first: 1, count: 20);
            Console.WriteLine($"first {sumNew.first}  count {sumNew.count}");

假设无怀念在概念写变量,那么可改var,作为变量

      (int first, int count) sum = ( 1,  20);
      Console.WriteLine($"first {sum.first}  count {sum.count}");

这里,类型int不能写 var

倘想不顶变量,那么只可以动用

            (int , int ) sum = ( 1,  20);
            Console.WriteLine($"first {sum.Item1}  count {sum.Item2}");

www.188bet .com 1
照作使用文化共享署名-非商业性使用-相同方法并享 4.0
国际许可协议
开展许可。欢迎转载、使用、重新公布,但得保留作品署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd
),不得用于商业目标,基于本文修改后底著作必须以相同的批准发表。如爆发另外问题,请和自身联系

当地函数

俺们好于函数里面定义函数,这是本地函数

<!–
这个在很多垃圾语言都有
–>

public int Fibonacci(int x)
{
    if (x < 0) throw new ArgumentException("Less negativity please!", nameof(x));
    return Fib(x).current;
    //下面 本地函数
    (int current, int previous) Fib(int i)
    {
        if (i == 0) return (1, 0);
        var (p, pp) = Fib(i - 1);
        return (p + pp, p);
    }
}

初阶小函数只谋面用同样次于,可是他的效果多,所以即便拿它写成道,于是一个好像就广大这种措施,只会师当一个函数使用,可是写成道,有时候开头看他,会认为方法很多,不知底哪位方法以哪用。

点说的凡这些尚未动用 vs 集团版的弟兄,其实生了铺面版,没有登时问题。

现在得利用其中函数,在一个函数里定义函数,看下边的代码,写一个斐波纳算法,可以直接以函数里套数,不需定义方法。

这用法在:迭代,异步

对于迭代器,抛来深在运,不是创办。

圈下这代码

public static IEnumerable<char> AlphabetSubset(char start, char end)
{
    if ((start < 'a') || (start > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
    if ((end < 'a') || (end > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");

    if (end <= start)
        throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");
    for (var c = start; c < end; c++)
        yield return c;
}

于输入不合法,就会丢掉来特别,那么抛来很是的早晚是什么

    var resultSet = Iterator.AlphabetSubset('f', 'a');
Console.WriteLine("iterator created");
foreach (var thing in resultSet)
  {
    Console.Write($"{thing}, ");
  }

可以看出在
var resultSet = Iterator.AlphabetSubset('f', 'a');无汇合摒弃来老,在
Console.Write($"{thing}, ");撇开来大。

生麻烦定位及是以哪的杀,出现非凡和了解好的,不以一个地点,这就是是事先运用迭代的一个较难以发现的。

所以做法是新建一个术迭代

    public static IEnumerable<char> AlphabetSubset2(char start, char end)
{
    if ((start < 'a') || (start > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
    if ((end < 'a') || (end > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");

    if (end <= start)
        throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");
    return alphabetSubsetImplementation(start, end);
}

private static IEnumerable<char> alphabetSubsetImplementation(char start, char end)
{ 
    for (var c = start; c < end; c++)
        yield return c;
}

这般虽可一定,不过问题是,可能错误调用 alphabetSubsetImplementation
,直接使用 他,不是运 AlphabetSubset2
,所以于初的C#,可以应用中方法

public static IEnumerable<char> AlphabetSubset3(char start, char end)
{
    if ((start < 'a') || (start > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(start), message: "start must be a letter");
    if ((end < 'a') || (end > 'z'))
        throw new ArgumentOutOfRangeException(paramName: nameof(end), message: "end must be a letter");

    if (end <= start)
        throw new ArgumentException($"{nameof(end)} must be greater than {nameof(start)}");

    return alphabetSubsetImplementation();

    IEnumerable<char> alphabetSubsetImplementation()
    {
        for (var c = start; c < end; c++)
            yield return c;
    }
}

而,在异步,假若出现分外,也是麻烦稳定,所以可以据此中方法以异步前判断好

    public Task<string> PerformLongRunningWork(string address, int index, string name)
{
    if (string.IsNullOrWhiteSpace(address))
        throw new ArgumentException(message: "An address is required", paramName: nameof(address));
    if (index < 0)
        throw new ArgumentOutOfRangeException(paramName: nameof(index), message: "The index must be non-negative");
    if (string.IsNullOrWhiteSpace(name))
        throw new ArgumentException(message: "You must supply a name", paramName: nameof(name));

    return longRunningWorkImplementation();

    async Task<string> longRunningWorkImplementation()
    {
        var interimResult = await FirstWork(address);
        var secondResult = await SecondStep(index, name);
        return $"The results are {interimResult} and {secondResult}. Enjoy.";
    }
}

当拔取异步函数前相当,不给开发者使用无校验的
longRunningWorkImplementation ,这便是其中方法的使用。

可是也许爆发兄弟这样写,让自家看是语言最垃圾

        public static void A()
        {
            A1();
            void A1()
            {
                void A2()
                {
                    void A3()
                    {

                    }
                }

                A2();
                //A3();
            }

            A1();
        }

<script type=”text/javascript”> $(function () { $(‘pre.prettyprint
code’).each(function () { var lines =
$(this).text().split(‘\n’).length; var $numbering =
$(‘<ul/>’).addClass(‘pre-numbering’).hide();
$(this).addClass(‘has-numbering’).parent().append($numbering); for (i =
1; i <= lines; i++) { $numbering.append($(‘<li/>’).text(i)); };
$numbering.fadeIn(1700); }); }); </script>

精益求精常量

咱有相比较充足数字,那么大家当概念需要相比难知晓他是否刻画对

咱得以拔取,下划线。这样是劈,可以屡屡我们描绘了多少数字,可以扣押我们是匪是描写错

var d = 123_456;
var x = 0xAB_CD_EF;

我们还得定义2进制,原来是心有余而力不足定义

var b = 0b1010_1011_1100_1101_1110_1111;

这些至关首要在二进制好,原先的动true和false,假设还要接纳,是由此byte转换,假若Iot,我们要定义二进制,假使用原的依旧难以,我尽管觉得那个效用好。可以分开,我们二上制好打在就窘迫,有矣细分雅观看没多只,这样看代码简单,这多少个职能应该是本`就可得到,现在使用_`觉得要没用。

ref returns 返回值

咱俩再次来到的凡引用,现在回可以是价值,我们回到数组中之一个价值,那么修改者价,因为放上引用,我们输出数组是修改的价值

public ref int Find(int number, int[] numbers)
{
    for (int i = 0; i < numbers.Length; i++)
    {
        if (numbers[i] == number) 
        {
            return ref numbers[i]; // return the storage location, not the value
        }
    }
    throw new IndexOutOfRangeException($"{nameof(number)} not found");
}

int[] array = { 1, 15, -39, 0, 7, 14, -12 };
ref int place = ref Find(7, array); 
place = 9; // 修改
WriteLine(array[4]); // 9

一体地方可以协理辣么大

从前协助辣么大的地方特别少,关于辣么大,参见
https://docs.microsoft.com/en-us/dotnet/articles/csharp/lambda-expressions

今昔好于享有地方用辣么大

    // Expression-bodied constructor
public ExpressionMembersExample(string label) => this.Label = label;

private string label;

// Expression-bodied get / set accessors.
public string Label
{
    get => label;
    set => this.label = value ?? "Default label";
}

每当众地方得放任分外

从前,相当是概念,所以下边代码出错

            private string _name;

        public string Name
        {
            set
            {
                _name = value??throw new ArgumentException();

            }
            get { return Name; }
        }

莫能够看清 name 空,同时老。

www.188bet .com 2

兹可

www.188bet .com 3

同时可以描绘

    private ConfigResource loadedConfig = LoadConfigResourceOrDefault() ?? 
    throw new InvalidOperationException("Could not load config");

广义异步再次来到路

以前 Task<>单纯会于法应用

    private async Task<int> loadCache()
{
    // simulate async work:
    await Task.Delay(100);
    cache = true;
    cacheResult = 100;
    return cacheResult;
}

今昔可采用 ValueTask<> 再次回到数值

    public ValueTask<int> CachedFunc()
{
    return (cache) ? new ValueTask<int>(cacheResult) : new ValueTask<int>(loadCache());
}
private bool cache = false;
private int cacheResult;
private async Task<int> loadCache()
{
    // simulate async work:
    await Task.Delay(100);
    cache = true;
    cacheResult = 100;
    return cacheResult;
}

顾接纳System.Threading.Tasks.Extension

本条形式可直接把数值转ValueTask

虽然并未就此,和事先的关押无起有什么用

            public static async ValueTask<int> ValueTask(int[] numbers)
        {
            if (!numbers.Any())
            {
                return 0;
            }
            else
            {
                return await Task.Run(() => numbers.Sum());
            }
        }

https://docs.microsoft.com/en-us/dotnet/articles/csharp/csharp-7

https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

VS 17 下载

VS 17 企业版

链接:http://pan.baidu.com/s/1skXDc3z 密码:70d6

使度盘链接没法使用,请联系自己。

代码 https://github.com/alugili/CSharp7Features

本文更新在:http://lindexi.oschina.io/lindexi/post/C-7.0/

www.188bet .com 4
遵照小说以知识共享署名-非商业性使用-相同方式一同享 4.0
国际许可协议
展开许可。欢迎转载、使用、重新发布,但必须保留作品署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd
),不得用于商业目的,基于本文修改后底创作必须以同等的特许揭橥。如发任何疑窦,请与己联系

<script type=”text/javascript”> $(function () { $(‘pre.prettyprint
code’).each(function () { var lines =
$(this).text().split(‘\n’).length; var $numbering =
$(‘<ul/>’).addClass(‘pre-numbering’).hide();
$(this).addClass(‘has-numbering’).parent().append($numbering); for (i =
1; i <= lines; i++) { $numbering.append($(‘<li/>’).text(i)); };
$numbering.fadeIn(1700); }); }); </script>

Leave a Comment.