在 C# 中,是否可以创建和应用实例方法字典?

In C#, is it possible to create and apply a Dictionary of instance methods?

我目前有以下方法:

        private FilterDefinition<BsonDocument> BuildFilters(GenericQueryParameters parameters)
        {
            FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
            FilterDefinition<BsonDocument> filters = filterBuilder.Empty;
            foreach (string filterString in parameters.Filters)
            {
                Match match = Regex.Match(filterString, @"(\w+)\s*([<>=]+)\s*(.*)", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string fieldName = match.Groups[1].Value;
                    string condition = match.Groups[2].Value;
                    string targetValue = match.Groups[3].Value;

                    if ("==".Equals(condition))
                    {
                        filters = filters & filterBuilder.Eq(fieldName, targetValue);
                    }
                    else if ("!=".Equals(condition))
                    {
                        filters = filters & filterBuilder.Ne(fieldName, targetValue);
                    }
                    else if ("<=".Equals(condition))
                    {
                        filters = filters & filterBuilder.Lte(fieldName, targetValue);
                    }
                    else if ("<".Equals(condition))
                    {
                        filters = filters & filterBuilder.Lt(fieldName, targetValue);
                    }
                    else if (">=".Equals(condition))
                    {
                        filters = filters & filterBuilder.Gte(fieldName, targetValue);
                    }
                    else if (">".Equals(condition))
                    {
                        filters = filters & filterBuilder.Gt(fieldName, targetValue);
                    }
                    else
                    {
                        throw new MalformedDatabaseFilterException($"The condition {condition} could not be applied.");
                    }
                }
                else
                {
                    throw new MalformedDatabaseFilterException($"The filter {filterString} could not be parsed.");
                }
            }

            return filters;
        }

这可行,但它很长且重复。 我想让它更像是:

        private static readonly Dictionary<string, Action> FilterBySymbols = new Dictionary<string, Action>() {
            {"==", FilterDefinitionBuilder<BsonDocument>.Eq },
            {"!=", FilterDefinitionBuilder<BsonDocument>.Ne },
            {"<=", FilterDefinitionBuilder<BsonDocument>.Lte },
            {"<", FilterDefinitionBuilder<BsonDocument>.Lt },
            {">=", FilterDefinitionBuilder<BsonDocument>.Gte },
            {">", FilterDefinitionBuilder<BsonDocument>.Gt }
        };
        private FilterDefinition<BsonDocument> BuildFilters(GenericQueryParameters parameters)
        {
            FilterDefinitionBuilder<BsonDocument> filterBuilder = Builders<BsonDocument>.Filter;
            FilterDefinition<BsonDocument> filters = filterBuilder.Empty;
            foreach (string filterString in parameters.Filters)
            {
                Match match = Regex.Match(filterString, @"(\w+)\s*([<>=]+)\s*(.*)", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string fieldName = match.Groups[1].Value;
                    string condition = match.Groups[2].Value;
                    string targetValue = match.Groups[3].Value;
                    if (FilterBySymbols.TryGetValue(condition, out Action action))
                    {
                        filters = filters & action(fieldName, targetValue);
                    }
                    else
                    {
                        throw new MalformedDatabaseFilterException($"The condition {condition} could not be applied.");
                    }
                }
                else
                {
                    throw new MalformedDatabaseFilterException($"The filter {filterString} could not be parsed.");
                }
            }
            return filters;
        }

...但这不会编译,因为操作都是实例方法。 此外,一旦我从映射中获取方法,就会出现一个悬而未决的问题,即如何将其应用于实例。

有什么想法whether/how我可以使更高版本工作吗?

你可以有一个 Dictionary<string, Action<FilterDefinitionBuilder<BsonDocument>, string, string>>。初始化为:

{ "==", (builder, fieldName, targetValue) => builder.Eq(fieldName, targetValue) },
{ "!=", (builder, fieldName, targetValue) => builder.Neq(fieldName, targetValue) }

并将其命名为:

if (FilterBySymbols.TryGetValue(condition, out Action action))
{
    action(filterBuilder, fieldName, targetValue);
}

就是说,我可能会使用 switch 表达式来编写它:这样会更清晰也更便宜:

filters = filters & condition switch
{
    "==" => filterBuilder.Eq(fieldName, targetValue),
    "!=" => filterBuilder.Neq(fieldName, targetValue),
    ...
    _ => throw new MalformedDatabaseFilterException($"The condition {condition} could not be applied.");
}