Проблема с Func <string> - PullRequest
       2

Проблема с Func <string>

0 голосов
/ 24 июня 2011
class Program
{
    static void Main()
    {
        int i = 0;
        whatever x = new whatever(i);
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
       public whatever(object variable)
       {
           this.variable = () => variable.ToString();
       }

       private Func<string> variable;
       public string data;

       public override string ToString()
       {
           data = variable();
           return data;
       }
}

Выход:

0
0

Что я хочу сделать, так это обновить значение I

Ответы [ 5 ]

6 голосов
/ 24 июня 2011

Если вы хотите захватить локальную переменную, то вы поместили лямбду в неправильном местеЛямбда должна идти туда, где она может быть закрыта по внешней переменной, которую вы хотите захватить.

class Program
{
    static void Main()
    {
        int i = 0;
        var x = new Whatever<int>(()=>i);
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }
}

class Whatever<T>
{
   private Func<T> variable;
   public Whatever(Func<T> func)
   {
       this.variable= func;
   }
   public override string ToString()
   {
       return this.variable().ToString();
   }
}

Имеет ли это смысл?Видите, лямбда должна быть там, где объявлено «i», так что «i» является внешней переменной лямбды, и поэтому лямбда видит изменения в ней.

3 голосов
/ 24 июня 2011

i - это целое число (тип значения), которое передается по значению - копия значения передается в любой конструктор.Когда вы изменяете его значение в методе Main, он не меняет того, что уже передано классу.Таким образом, вы не можете получить обновленное значение для whatever.

Если у вас есть объект, который содержит поле целочисленного значения, а затем передать этот объект в whatever, тогда изменения в этом поле будутотразиться на классе.

1 голос
/ 24 июня 2011

Возможно, проблема в том, что делегат привязан к целочисленным данным в штучной упаковке. Вот почему вы меняете свой int и делегируете оценки на старые данные в штучной упаковке.

Попробуйте с конструктором, который принимает int.

Но, да, верно, что целые числа делятся на значения, так что это не будет работать. Передать делегата в ctor.

class Program
{
        static void Main()
        {
            int i = 0;
        whatever x = new whatever(() => i.ToString());
        Console.WriteLine(x);
        i = 1;
        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
        public whatever(Func<string> someFunc)
        {
            this.variable = someFunc;
        }

        private Func<string> variable;
        public string data;

        public override string ToString()
        {
            data = variable();
            return data;
        }
    }
 }

Выход: 0 1

Или, как другие указали:

class Program
{
    static void Main()
    {
        var myRefType = new MyRefType();
        myRefType.MyInt = 0;

        var x = new whatever(myRefType);
        Console.WriteLine(x);
        myRefType.MyInt = 1;

        Console.WriteLine(x);
        Console.ReadKey();
    }

    class whatever
    {
        public whatever(MyRefType myRefType)
        {
            this.variable = () => myRefType.MyInt.ToString();
        }

        private Func<string> variable;

        public override string ToString()
        {
            return variable();
        }
    }

    class MyRefType
    {
        public int MyInt { get; set; }
    }
}

Выходы: 0 1

0 голосов
/ 24 июня 2011

int является типом значения, то есть его значение копируется каждый раз, когда вы его используете, а не его ссылка.Лучший способ сделать эту работу - сделать тип ссылки вокруг int:

class IntRef
{
    public int Val;
}

Вам нужно будет всегда использовать IntRef.Val, а передача самого IntVal сохранит ссылку.

0 голосов
/ 24 июня 2011

Целые числа имеют тип значения, а не ссылочный тип.

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