2014-07-15 5 views
2

Вдохновленный JavaScript Closures Я пытался имитировать локальные статические переменные в C# с помощью Func <> Делегирование ... Вот мой код ..Локальная статическая переменная в C#?

public Func<int> Increment() 
    { 
     int num = 0; 
     return new Func<int>(() => 
     { 
      return ++num; 
     }); 
    } 

Func<int> inc = Increment(); 
Console.WriteLine(inc());//Prints 1 
Console.WriteLine(inc());//Prints 2 
Console.WriteLine(inc());//Prints 3 

Я стремлюсь знать, есть ли какой-либо другой способ моделирования локальная статическая переменная в C#? Спасибо.

+3

Где статическая переменная? – Arjuna

+1

@Arjuna: Я предполагаю, что они ссылаются на 'num', который становится частью замыкания и к нему нельзя обращаться иначе. –

+8

Путем создания статической переменной C# было бы фактически создать класс с элементом' static'. Это похоже на то, что вы спрашиваете: «Как я могу заставить C# вести себя как Javascript?» который, я думаю, ответ должен быть «не надо». Это два разных языка, и заставить одного действовать, как и другого, только закончится слезами. –

ответ

5

Это абсолютно ужасно, но одним из способов было бы использовать метод итератора и отбросить выход. Например, если вы хотите:

public void PrintNextNumber() 
{ 
    static int i = 0; //Can't do this in C# 
    Console.Out.WriteLine(i++); 
} 

Вы могли бы вместо того, чтобы написать:

public IEnumerator<object> PrintNextNumber() 
{ 
    int i = 0; 
    while (true) 
    { 
     Console.Out.WriteLine(i++); 
     yield return null; 
    } 
} 

Тогда вместо вызова PrintNextNumber(), вы могли бы сделать var printNext = PrintNextNumber(); printNext.MoveNext;.

Я действительно только написал этот ответ для удовлетворения любопытства, я абсолютно был бы не рекомендую действительно делать это!

Это становится еще более противным, если вы действительно хотите что-то вернуть из метода, но это possible- вы можете yield return вместо этого, а затем получить его с помощью Current, вызвав MoveNext

+1

Это не делает значение 'static'. 'PrintNextNumber(). MoveNext' всегда будет * печатать' 0', потому что новый счетчик создается каждый раз, когда вы вызываете 'PrintNextNumber'. Единственный способ получить желаемое поведение - сохранить перечислитель в статической переменной, чтобы публичный метод мог вернуть его или получить следующее значение, что, конечно, не соответствует требованию не иметь статического поля. – Servy

+0

@Servy Правильно. Я обновил ответ –

+0

Nice one @BenAaronson :) – Uthaiah

Смежные вопросы