【问题标题】:Delegate chain method results to function body将链方法结果委托给函数体
【发布时间】:2021-03-15 00:26:07
【问题描述】:

尝试构建格式化委托/函数。主要用于打印练习结果。 我正在尝试访问参数的结果,但我认为我对代表的理解仍然有点糟糕。该方法在块本身中是可调用的,但我想要结果,目前它打印结果定义。 System.Func2[ConsoleApp1.LoanQueries,System.Collections.Generic.IEnumerable1[System.Decimal]]

下面是创建解析结果的代码、解析方法和我的代码基于的代码 sn-p。

我的问题是

  • 这是可能的还是我违反了一些规则?(尝试使用表达式/函数)
  • 是否可以只声明一个委托而不是函数(这可能涉及每次格式化而不是函数。)

创建要格式化的数据

       // Method bodied expression
       public IEnumerable<decimal> LoanQueryBodied =>
            from amount in LoanAmounts
            where amount % 2 == 0
            orderby amount ascending
            select amount;

        // Query expression:
        public IEnumerable<decimal> LoanQueryExpression () =>
            LoanAmounts
                .Where(a => a % 2 == 0)
                .OrderBy(r => r);

数据和最终格式化的方法

public static void FormatLoans<TObject>(
            Func<TObject> instance,
            Func<TObject, IEnumerable<decimal>> function)
        {
            // This is the function object but should be IEnumerable<decimal> result passed down.
            // Just like TObject is passed , but how?
            Console.WriteLine(string.Join(" - ",function));
        }

使用方法

             LoanQueries.FormatLoans<LoanQueries>(() =>
                    new LoanQueries()
                , inst => inst.LoanQueryBodied);

             LoanQueries.FormatLoans<LoanQueries>(() =>
                    new LoanQueries()
                , inst => inst.LoanQueryExpression());

我松散地基于它的代码

 public static class Disposable
    {
        public static TResult Using<TDisposable, TResult>(
            Func<TDisposable> factory,
            Func<TDisposable, TResult> map)
            where TDisposable : IDisposable
        {
            using (var disposable = factory())
            {
                return map(disposable);
            }
        }
    }

调用的示例

            var time= Disposable
                .Using(
                    () => new WebClient(),
                    client => XDocument.Parse(client.DownloadString("http://time.gov/actualtime.cgi")))
                .Root
                .Attribute("time")
                .Value;

我想像这样链接我的方法,但如果这是不可能的或不好的做法,我也想知道。

【问题讨论】:

  • 您收到什么错误信息?你从哪里弄来的?
  • 是的,可能在解释中迷路了,在传递 'function' 参数的 'FormatLoans' 中,它打印 'System.Func2[ConsoleApp1.LoanQueries,System.Collections.Generic.IEnumerable1[System.Decimal]]' 我想要结果在函数体中格式化该函数。这是不可能的吗?示例代码似乎是这样做的,还是只是传递函数?
  • 您需要调用该函数。 Console.WriteLine(string.Join(" - ",function(instance())));
  • 感谢提及invoke方法,不知道这个。我标记为答案的帖子也提到了这一点,并添加了一些额外的 cmets/tips。您的解决方案非常适合委托方法。

标签: c# functional-programming delegates func


【解决方案1】:

您需要使用() 调用functioninstance

Console.WriteLine(string.Join(" - ",function(instance())));

显然你想返回字符串,而不是打印它,以允许链接,所以:

public static string FormatLoans<TObject>(
        Func<TObject> instance,
        Func<TObject, IEnumerable<decimal>> function) =>
    string.Join(" - ",function(instance()));

但是,我认为您确实过于复杂/过度概括了这一点。您的方法不像您展示的Disposable.Using 方法那样通用。你的方法可以这样声明:

public static string FormatLoans(IEnumerable<decimal> loans) =>
    string.Join(" - ", loans);

来电者:

LoanQueries.FormatLoans(new LoanQueries().LoanQueryBodied)
LoanQueries.FormatLoans(new LoanQueries().LoanQueryExpression)

Disposable.Using 使用委托,因为它试图重新创建 using statement。第二个参数必须在using 语句中进行评估,以便抛出的任何异常都会导致IDisposable 的处置,这就是为什么它必须包含在委托中的原因。如果不是,则第二个参数将在 Using 方法运行之前进行评估,这样就错过了重点。

但是,您的方法没有这样的特殊要求,因此您不需要委托。

【讨论】:

  • 我不知道实例方法,谢谢。哎呀,返回类型仍然很旧。是的,代表并不真正适合这个,我正在尝试更多地了解代表。还要特别感谢您对示例代码和原因发表评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多