2010-02-03 4 views
1

기능적 C#을 배우려고 시도했지만 Dustin Campbell의 fibonacci example을 C# 3에 이식했습니다. 내 솔루션 작동하지만 Nth_Fib 마지막 줄을 이해하는 데 문제가 있습니다. 수식에 대한 악기가 중요하지 않은 것은 이상하지 않습니까? n은 "fn => Nth_Fib (n - 1) + Nth_Fib (n - 2)"표현식에 즉시 바인드되지만 Func 에 대한 반환 유형을 Func <으로 변경할 수 없습니다. 이것은 나중에 중복 된 인수를 전달해야 함을 의미합니까?C# 클로저를 사용하여이 fibonacci 예제를 이해할 수 있습니까?

참고 : 테스트는

[TestFixture] 
public class TestFibClosure{ 
    [Test] 
    public void test_fib(){ 
     Assert.AreEqual(8, new FibClosure().Nth_Fib(5)); 
     Assert.AreEqual(1597, new FibClosure().Nth_Fib(16)); 
    } 
} 

public class FibClosure{ 
    private Func<int, int>[] formulaCache; 

    public int Nth_Fib(int n){ 
     if (n <= 2) return n; 
     if(formulaCache == null) formulaCache = new Func<int, int>[(n + 1)]; 
     Func<int, int> formula = build(n); 
     //doesn't matter, n is already bound !! ?? 
     return formula(334567);//same as formula(n) 
    } 

    private Func<int, int> build(int n){ 
     if (formulaCache[n] == null) 
      formulaCache[n] = (fn => Nth_Fib(n - 1) + Nth_Fib(n - 2)); 
     return formulaCache[n]; 
    } 
} 
+0

음 폐쇄? – PeanutPower

+0

@PeanutPower : 예 - 그것들은 어떻습니까? –

+0

@Jon 익명 메소드가 아닌 C#에서 진정한 클로저를 생성 할 수 있습니까? – PeanutPower

답변

4

당신은 Func<int>에 유형을 변경할 수 있습니다 전달 - 당신은 그냥 사방에 그것을 할 수있어 :

public class FibClosure{ 
    private Func<int>[] formulaCache; 

    public int Nth_Fib(int n){ 
     if (n <= 2) return n; 
     if(formulaCache == null) formulaCache = new Func<int>[(n + 1)]; 
     Func<int> formula = build(n); 
     return formula(); 
    } 

    private Func<int> build(int n){ 
     if (formulaCache[n] == null) 
      formulaCache[n] =() => Nth_Fib(n - 1) + Nth_Fib(n - 2); 
     return formulaCache[n]; 
    } 
} 

당신은 인수가 필요하지 않습니다를 함수의 경우 피보나치 값은 고정되어 있기 때문에 기본적으로 formulaCache[x]fib(x)을 계산합니다. 이 사실에 대한 단서는 어쨌든 의 람다 식에서 fn을 사용하지 않았다는 사실이었습니다. 나는이 인정 하듯이, 구조화 것들을 몹시 명확한 방법이다라고 말하고 싶지만 확실하지 않다

... C#에서

+0

을 참조하십시오. 나는 arg-lambda에 대해() => 구문을 놓쳤다. – ottodidakt

관련 문제