gpt4 book ai didi

c# - 在 C# 中实现模式匹配

转载 作者:IT王子 更新时间:2023-10-29 04:48:12 25 4
gpt4 key购买 nike

在 Scala 中,您可以使用模式匹配来根据输入的类型生成结果。例如:

val title = content match {
case blogPost: BlogPost => blogPost.blog.title + ": " + blogPost.title
case blog: Blog => blog.title
}

在 C# 中,我希望能够编写:

var title = Visit(content,
(BlogPost blogPost) => blogPost.Blog.Title + ": " + blogPost.Title,
(Blog blog) => blog.Title
);

这可能吗?当我尝试将其作为单一方法编写时,我不知道如何指定泛型。以下实现似乎是正确的,除了让类型检查器允许函数接受 T 的子类型:

    public TResult Visit<T, TResult>(T value, params Func<T, TResult>[] visitors)
{
foreach (var visitor in visitors)
{
if (visitor.Method.GetGenericArguments()[0].IsAssignableFrom(value.GetType()))
{
return visitor(value);
}
}
throw new ApplicationException("No match");
}

我得到的最接近的方法是将函数单独添加到一个对象,然后调用一个值的访问:

    public class Visitor<T, TResult>
{
private class Result
{
public bool HasResult;
public TResult ResultValue;
}

private readonly IList<Func<T, Result>> m_Visitors = new List<Func<T, Result>>();

public TResult Visit(T value)
{
foreach (var visitor in m_Visitors)
{
var result = visitor(value);
if (result.HasResult)
{
return result.ResultValue;
}
}
throw new ApplicationException("No match");
}

public Visitor<T, TResult> Add<TIn>(Func<TIn, TResult> visitor) where TIn : T
{
m_Visitors.Add(value =>
{
if (value is TIn)
{
return new Result { HasResult = true, ResultValue = visitor((TIn)value) };
}
return new Result { HasResult = false };
});
return this;
}
}

可以这样使用:

var title = new Visitor<IContent, string>()
.Add((BlogPost blogPost) => blogPost.Blog.Title + ": " + blogPost.Title)
.Add((Blog blog) => blog.Title)
.Visit(content);

知道如何通过单个方法调用来做到这一点吗?

最佳答案

模式匹配是 F# 等函数式编程语言中常见的可爱功能之一。 codeplex 中正在进行一个名为 Functional C# 的伟大项目.考虑以下 F# 代码:

let operator x = match x with
| ExpressionType.Add -> "+"

let rec toString exp = match exp with
| LambdaExpression(args, body) -> toString(body)
| ParameterExpression(name) -> name
| BinaryExpression(op,l,r) -> sprintf "%s %s %s" (toString l) (operator op) (toString r)

使用 Functional C# 库,C# 等效项为:

var Op = new Dictionary<ExpressionType, string> { { ExpressionType.Add, "+" } };

Expression<Func<int,int,int>> add = (x,y) => x + y;

Func<Expression, string> toString = null;
toString = exp =>
exp.Match()
.With<LambdaExpression>(l => toString(l.Body))
.With<ParameterExpression>(p => p.Name)
.With<BinaryExpression>(b => String.Format("{0} {1} {2}", toString(b.Left), Op[b.NodeType], toString(b.Right)))
.Return<string>();

关于c# - 在 C# 中实现模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6031555/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com