在C#中实现模式匹配在Scala中,您可以使用模式匹配根据输入的类型生成结果。例如:valtitle=contentmatch{caseblogPost:BlogPost=>blogPost.blog.title+":"+blogPost.titlecaseblog:Blog=>blog.title}在C#中,我最好能够编写:vartitle=Visit(content,(BlogPostblogPost)=>blogPost.Blog.Title+":"+blogPost.Title,(Blogblog)=>blog.Title);这可能吗?当我尝试将其编写为单个方法时,我不知道如何指定泛型。下面的实现看起来是正确的,除了让类型检查器允许函数接受T的子类型:publicTResultVisit(Tvalue,paramsFunc[]visitors){)[0].IsAssignableFrom(value.GetType())){返回访问者(值);}}thrownewApplicationException("不匹配");我最接近的是分别将函数添加到对象,然后调用访问者值:publicclassVisitor{privateclassResult{publicboolHasResult;公共TResult结果值;}privatereadonlyIListm_Visitors=newList();publicTResultVisit(Tvalue){foreach(varvisitorinm_Visitors){varresult=visitor(value);如果(result.HasResult){返回结果.ResultValue;}}thrownewApplicationException("不匹配");}publicVisitorAdd(Funcvisitor)whereTIn:T{m_Visitors.Add(value=>{if(valueisTIn){返回新结果{HasResult=true,ResultValue=visitor((TIn)value)};}returnnew结果{HasResult=false};});归还这个;这有效像这样使用:vartitle=newVisitor().Add((BlogPostblogPost)=>blogPost.Blog.Title+":"+blogPost.Title).Add((Blogblog)=>blog.Title).Visit(content);知道如何用单一方法调用它吗?使用函数式C#(来自@Alireza)vartitle=content.Match().With(blogPost=>blogPost.Blog.Title+":"+blogPost.Title).With(blog=>blog.Title).Result();模式匹配是F#等函数式编程语言中最常见的功能之一,在Codeplex中有一个名为FunctionalC#的很棒的项目。考虑以下F#代码:letoperatorx=matchxwith|ExpressionType.Add->"+"letrectoStringexp=matchexpwith|LambdaExpression(args,body)->toString(body)|参数表达式(名称)->名称|BinaryExpression(op,l,r)->sprintf"%s%s%s"(toStringl)(operatorop)(toStringr)使用FunctionalC#库,C#等效项为:varOp=newDictionary{{ExpressionType.Add,"+"}};表达式>添加=(x,y)=>x+y;函数toString=null;toString=exp=>exp.Match().With(l=>toString(l.Body)).With(p=>p.Name).With(b=>String.Format("{0}{1}{2}",toString(b.Left),Op[b.NodeType],toString(b.Right))).Return();为确保完全模式匹配,您需要将函数构建到类型本身中。我这样做:publicabstractclassContent{privateContent(){}publicabstractTMatch(FuncconvertBlog,FuncconvertPost);publicclassBlog:Content{publicBlog(stringtitle){Title=title;}公共字符串标题{得到;私有集;}publicoverrideTMatch(FuncconvertBlog,FuncconvertPost){returnconvertBlog(this);}}publicclassBlogPost:Content{publicBlogPost(stringtitle,Blogblog){Title=title;博客=博客;}公共字符串标题{得到;私有集;}公共博客博客{得到;私有集;}publicoverrideTMatch(FuncconvertBlog,FuncconvertPost){returnconvertPost(this);}}}publicstaticclassExample{publicstaticstringGetTitle(Contentcontent){returncontent.Match(blog=>blog.Title,post=>post.Blog.Title+":"+post.Title);查看我的模式匹配实现:repo它基于表达式,因此它提供与嵌套ifs相同的性能。使用方法示例:strings1="Hello";字符串s2=空;Func>match=newMatcher>{{s=>sisNone,s=>Console.WriteLine("None")},{s=>sisSome,s=>Console.WriteLine((string)s)//或s.Value};匹配(s1);//你好match(s2);//None可以通过NuGet:Nuget包获得我正在使用的实际应用,可以匹配类型,条件或值:publicstaticclassMatch{publicstaticPatternMatchWith(Tvalue){returnnewPatternMatch(value);}publicstructPatternMatch{privatereadonlyT_value;私人R_result;私人布尔_matched;publicPatternMatch(Tvalue){_value=value;_匹配=假;_result=默认值(R);}publicPatternMatchWhen(Funccondition,Funcaction){if(!_matched&&condition(_value)){_result=action();_匹配=真;}返回这个;}publicPatternMatchWhen(Funcaction){if(!_matched&&_valueisC){_result=action((C)(object)_value);_匹配=真;}返回这个;}publicPatternMatchWhen(Cvalue,Funcaction){if(!_matched&&value.Equals(_value)){_result=action();_匹配=真;}返回这个;}公共R结果=>_result;publicRDefault(Funcaction){return!_matched?动作():_结果;在你的例子中,用法看起来像:Match.With(content).When(blogPost=>blogPost.Blog.Title).When(blog=>blog.Title).Result;//或者只是.Default(()=>"none");其他一些例子:以上是《C#学习教程:在C#中实现模式匹配》的全部内容。如果对你有用,需要进一步了解《C#学习教程》,希望你多多关注——varresult=Match.With(newFoo(){A=5}).When(foo=>foo.A).When(bar=>bar.B).When(Convert.ToInt32).Result;Assert.Equal(5,结果);varresult=Match.With(n).When(x=>x>100,()=>"n>100").When(x=>x>10,()=>"n>10")。默认(()=>“”);Assert.Equal("n>10",结果);varresult=Match.With(5).When(1,()=>"1").When(5,()=>"5").Default(()=>"e");Assert.Equal("5",结果);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: