Можно ли объявить и использовать анонимную функцию в одном выражении? - PullRequest
3 голосов
/ 28 марта 2009

Есть ли способ объединить следующие две строки в один оператор?

Func<XmlNode> myFunc = () => { return myNode; };
XmlNode myOtherNode = myFunc();

Я пробовал что-то подобное ниже, но не могу заставить его работать и не могу определить из документации, должно ли оно работать или нет?

XmlNode myOtherNode = ((Func<XmlNode>) () => { return myNode; })();

Ответы [ 4 ]

6 голосов
/ 28 марта 2009

Я не уверен, почему вы хотите это сделать, но ..

XmlNode myOtherNode = new Func<XmlNode>( () => { return myNode; } )();

должен сделать трюк.

2 голосов
/ 28 марта 2009

Синтаксис, размещенный "Headsling" работает.

Как ни странно, даже если вы не можете использовать оригинальный синтаксис с лямбдой (=>), вы можете использовать с delegate:

XmlNode myOtherNode = ((Func<XmlNode>) delegate { return myNode; })();

Конечно, настоящий вопрос ... почему? Что не так с ...

XmlNode myOtherNode = myNode;
2 голосов
/ 28 марта 2009

Хитрость заключается в том, что вам нужно создать экземпляр делегата, чтобы он работал, что в вашем примере - простота, выполняемая при выполнении назначения (myFunc = ...). Кроме того, вы можете выразить свою функцию как () => myNode, чтобы сделать ее короче.

XmlNode myOtherOne = new Func<XmlNode>( () => myNode )();
0 голосов
/ 20 апреля 2011

Просто подумал, что я добавлю еще один интересный пример использования этой конструкции в смесь:

namespace FunWithContractsAndAnonymousDelegates
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;

    internal static class Program
    {
        private static void MySort<T>(T[] array, int index, int length, IComparer<T> comparer)
        {
            Contract.Requires<ArgumentNullException>(array != null);
            Contract.Requires<ArgumentOutOfRangeException>(index >= 0 && index <= array.Length);
            Contract.Requires<ArgumentOutOfRangeException>(length >= 0 && index + length <= array.Length);
            Contract.Ensures(new Func<T[], int, int, IComparer<T>, bool>((_array, _index, _length, _comparer) =>
                {
                    T[] temp = (T[])_array.Clone();
                    Array.Sort(temp, _index, _length, _comparer);
                    return temp.SequenceEqual(_array);
                })(array, index, length, comparer));

            // TODO: Replace with my heavily optimized and parallelized sort implementation...
            Array.Sort(array, index, length, comparer);
        }

        private static void Main(string[] args)
        {
            int[] array = { 3, 2, 6, 1, 5, 0, 4, 7, 9, 8 };
            MySort(array, 0, array.Length, Comparer<int>.Default);
            foreach (int value in array)
            {
                Console.WriteLine(value);
            }
        }
    }
}

Объявление и вызов анонимных делегатов означает, что мне не нужно объявлять метод, который я буду использовать только один раз для проверки постусловия (т.е. при вызове Contract.Ensures).

Каким бы вымышленным это ни выглядело, сегодня я использовал это по-настоящему ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...