代码之家  ›  专栏  ›  技术社区  ›  Glorfindel Craig Stuntz

有没有办法声明一个C#lambda并立即调用它?

  •  4
  • Glorfindel Craig Stuntz  · 技术社区  · 5 年前

    Func<int, int> lambda = (input) => { return 1; };
    int output = lambda(0);
    

    我想知道是否可以在一行中这样做,例如

    int output = (input) => { return 1; }(0);
    

    它给出了一个编译器错误“需要方法名”。铸造到 Func<int, int> 也不起作用:

    int output = (Func<int, int>)((input) => { return 1; })(0);
    

    int ).


    你可能在想 我想这样做,而不是直接嵌入代码。 int output = 1; . 原因如下:我为SOAP webservice生成了一个引用 svcutil

    var o = await client.GetOrderAsync(request);
    return new Order {
        OrderDate = o.OrderDate,
        ...
        Shipments = o.Shipment_Order == null ? new Shipment[0]
            o.Shipment_Order.Select(sh => new Shipment {
                ShipmentID = sh.ShipmentID,
                ...
                Address = CreateAddress(sh.ReceiverAddress_Shipment);
            }).ToArray()
    };
    

    和一个单独的 CreateAddress(GetOrderResultOrderShipment_OrderShipmentShipment_Address address) 方法(实名甚至更长,我对表单的控制非常有限),我想编写

    var o = await client.GetOrderAsync(request);
    return new Order {
        OrderDate = o.OrderDate,
        ...
        Shipments = o.Shipment_Order == null ? new Shipment[0]
            o.Shipment_Order.Select(sh => new Shipment {
                ShipmentID = sh.ShipmentID,
                ...
                Address = sh.ReceiverAddress_Shipment == null ? null : () => {
                    var a = sh.ReceiverAddress_Shipment.Address;
                    return new Address {
                        Street = a.Street
                        ...
                    };
                }()
            }).ToArray()
    };
    

    Address = sh.ReceiverAddress_Shipment == null ? null : new Address {
        Street = sh.ReceiverAddress_Shipment.Address.Street,
        ...
    }
    

    但即使如此 sh.ReceiverAddress_Shipment.Address 如果有许多字段,则会变得非常重复。声明一个lambda并立即调用它 更优雅

    4 回复  |  直到 5 年前
        1
  •  5
  •   Glorfindel Craig Stuntz    5 年前

    我建议您使用一个小的helper函数,而不是尝试转换lambda:

    public static TOut Exec<TIn, TOut>(Func<TIn, TOut> func, TIn input) => func(input);
    

    你可以这样使用: int x = Exec(myVar => myVar + 2, 0); . 这对我来说要比这里建议的替代方案好得多。

        2
  •  4
  •   Johnathan Barclay    5 年前

    很难看,但有可能:

    int output = ((Func<int>)(() => { return 1; }))();
    

    可以强制转换,但lambda需要括在括号中。

    以上也可以简化:

    int output = ((Func<int>)(() => 1))();
    
        3
  •  1
  •   Cyril Durand    5 年前

    您还可以在 Select 方法

    var o = await client.GetOrderAsync(request);
    return new Order {
        OrderDate = o.OrderDate,
        ...
        Shipments = o.Shipment_Order == null ? new Shipment[0]
            o.Shipment_Order.Select(sh => {
              var s = sh.ReceiverAddress_Shipment;
              var a = s.Address;
              return new Shipment {
                ShipmentID = sh.ShipmentID,
                ...
                Address = s == null ? 
                          null : 
                          new Address {
                            Street = a.Street
                            ...
                          }
              };
            }).ToArray()
    };
    

    ?? 操作人员

    var o = await client.GetOrderAsync(request);
    return new Order {
        OrderDate = o.OrderDate,
        ...
        Shipments = o.Shipment_Order?.Select(sh => {
            var s = sh.ReceiverAddress_Shipment;
            var a = s.Address;
            return new Shipment {
                ShipmentID = sh.ShipmentID,
                ...
                Address = s == null ? 
                          null : 
                          new Address {
                              Street = a.Street
                              ...
                          }
            };
        }).ToArray() ?? new Shipment[0]
    };
    
        4
  •  1
  •   Glorfindel Craig Stuntz    5 年前

    您可以内联 Func

    int output = (new Func<int, int>(() => { return 1; }))(0);
    

    立即调用它。