Zen 및 Functional C#

함수식 프로그래밍을 작성하면 선종과 유사한 체험을 불러일으킬 수 있다.깨끗하고 짧은 코드 블록으로 그들의 의도와 내부 작업 원리를 똑똑히 보여 줍니다. 함수 C#이 매듭을 풀고 공간을 정리했습니다.

부작용이 더 없어요.


숨을 들이마시다.5초를 유지하다.내지르다
이제는 기능적으로 생각할 때다. 싫고 좋지 않은 부작용에 대해 안녕히 계세요.

  • Side effects은 현재 범위 밖의 상태를 수정할 때 프로그램의 다른 곳에서 자신도 모르게 상태를 변경합니다.이것은 불필요한 행위와 불필요한 인과관계를 초래할 수 있다.
  • 은 부작용이 없는 기능을 더 좋아한다.이 함수들을 pure functions이라고 부른다.(면책 성명: 순수함수 작성은 중독되기 쉬워 - 시작하면 멈출 수 없음)
  • 선종법전 건의:


    피: 불순 함수
    public void UpdatePrice(decimal vat, decimal cost, decimal markup)
    {
        this.price = (cost + markup) * (1 + vat);
    }
    
    기본 설정: 순수 함수
    public decimal PriceIncludingVat(decimal vat, decimal cost, decimal markup)
    {
        return (cost + markup) * (1 + vat);
    }
    
    price = PriceIncludingVat(0.2m, 10m, 2m);
    
    PriceIncludingVat을 호출하면 기존 상태를 수정하지 않습니다.새 상태로 돌아갑니다.너는 그것을 임의로 여러 번 호출할 수 있다. 네가 그것을 진정으로 설정하기 전에, 너의 현재 price은 영향을 받지 않을 것이다.
    더 긴 불순한 방법으로 순함수를 만드는 연습을 하다.방법의 부작용을 타파하고 이를 자신의 함수로 바꾸어 새로운 상태로 되돌려준다.너는 자신이 진정으로 싫은 문제를 해결했다는 것을 알게 될 것이다. 이것은 선종에 더욱 가까워지는 것이다.

    불변성


    눈을 감다.숨을 들이마시다.숨을 내쉬다.immutability의 평온을 안아주다.

    너의 주는 더 이상 변할 수 없을 것이다.new, 구형.객체를 변경할 수 없으므로 객체를 변경할 수 없습니다.이것은 부작용을 완전히 방지할 수 있다.변경된 속성을 변경할 수 없는 객체에서 구현하는 유일한 방법은 변경이 포함된 새 객체로 대체하는 것입니다.

    선종법전 건의:


    피해: 가변 객체
    public class ZenGarden
    {
        public int Tranquillity { get; set; } // mutable
        public int Peace { get; set; } // mutable
    
        public ZenGarden(int tranquillity, int peace)
        {
            Tranquillity = tranquillity;
            Peace = peace;
        }
    }
    
    이로 인해
    var garden = new ZenGarden(10, 20);
    garden.Peace = -1000;
    // or even worse
    public int TranquilityAndPeace(ZenGarden garden)
    {
        garden.Peace -= 1; // a side effect
        return garden.Tranquillity + garden.Peace;
    }
    
    기본 설정:
    public class ZenGarden
    {
        public readonly int Tranquillity;
        public readonly int Peace;
    
        public ZenGarden(int tranquillity, int peace)
        {
            Tranquillity = tranquillity;
            Peace = peace;
        }
    }
    
    이로 인해
    var garden = new ZenGarden(10, 20);
    garden = new ZenGarden(10, 21); // peace goes up, because of immutability :]
    // pure function
    public int TranquilityAndPeace(ZenGarden garden)
    {
        var calculatedGarden = new ZenGarden(garden.Tranquillity, garden.Peace - 1);
        return calculatedGarden .Tranquillity + calculatedGarden .Peace;
    }
    
  • 개인 setter 대신 readonly을 사용하여 class 자체에서도 값을 변경할 수 없음을 주의하십시오.
  • 불필요한 변화(부작용)를 걱정하지 않는다. - 불변성은 똑같은 상태가 바뀌지 않도록 확보하고, race conditionsthread locks에게 우호적으로 작별을 고한다.

    참조 투명도


    선명한 선의를 품다.referentially transparent 함수는 호출할 때 되돌아오는 값으로 바꿀 수 있습니다.상하문이 어떻든지 간에 그것은 같은 매개 변수에 대해 같은 값을 되돌려 줄 것이다.불투명 함수를 인용하는 작용은 상반된다. - 일반적으로 변경될 수 있는 외부 값을 인용했기 때문이다.
    인용 투명성은 코드를 더욱 명확하게 읽는 데 도움이 된다.그것은 그 범위 밖에서 값을 얻는 함수를 풀었고, 반환값을 계산할 때 그 매개 변수에만 작용하도록 제한했다.
    그것은 함수를 격리하여 코드의 외부 변경을 받지 않도록 보호한다.

    선종법전 건의:


    피해: 불투명 함수
    public double PriceOfFood(double price) 
    {
        // if the number of people changes, the price of food changes
        // regardless of price changing
        return this.numberOfPeople * price;
    }
    
    기본 설정: 투명 함수
    public double PriceOfFood(double price, int numberOfPeople) 
    {
        return numberOfPeople * price;
    }
    

    고급 함수


    도중에 모두 일류의 아기들이다.우리는 이러한 기능을 들고 공민을 대하는 것처럼 그들을 대하기 시작했다.C#first-class citizens과 같은 함수를 처리합니다.이것은 함수가 방법의 매개 변수로 사용할 수 있다는 것을 의미한다.함수는 변수에 분배할 수 있다.함수는 다른 함수에서 되돌아올 수도 있다.
    함수를 일급 공민으로 사용하면 코드를 몇 개의 작은 구축 블록으로 분해할 수 있고 모든 구축 블록은 약간의 (깨끗하고 순수하며 투명하길 바란다) 기능을 봉인한다.이 작은 블록들은 다양한 기능을 얻기 위해 많은 조합에서 사용할 수 있다.우리의 수요가 변화할 때, 그것들은 조정하고 교환할 수 있으며, 코드 라이브러리에 대한 영향은 매우 적다.

    필요에 따라 기능 생성 - 대량의 코드를 작성하지 마십시오.함수를 우리가 알고 있는 운동 부품처럼 실행시키다.
    Higher-order functions은 함수를 매개 변수 또는 반환 함수로 합니다.C#은 함수를 일등 공민으로 간주하기 때문에 as가 고급 함수를 만들 수 있도록 합니다.

    선종법전 건의:


    모면: 잘 모르는 lambdas
    var range = Enumerable.Range(-20, 20);
    range.Where(i => i % 2 == 0);
    range.Where(i => i % 5 != 0);
    
    기본 설정: 함수 이름 지정
    Func<int, bool> isMod(int n) => i => i % n == 0;
    range.Where(isMod(true, 2));
    range.Where(!isMod(false, 5));
    
    피하기: 프로그램 기능 호출 (적용 가능)
    public class Car {...}
    
    public void ChangeOil(Car car) {...}
    public void ChangeTyres(Car car) {...}
    public void Refuel(Car car) {...}
    
    public void PitStop(Car car)
    {
        ChangeOil(car);
        ChangeTyres(car);
        Refuel(car);
    }
    
    PitStop(car);
    
    기본 설정: 동적 함수 호출 (해당하는 경우)
    public class Car {...}
    
    public void ChangeOil(Car car) {...}
    public void ChangeTyres(Car car) {...}
    public void Refuel(Car car) {...}
    
    public void PitStop(Car car, IEnumerable<Action<Car>> pitstopRoutines)
    {
        foreach(var routine in pitstopRoutines)
            routine(car);
    }
    
    PitStop(car, new List<Action<Car>>{ChangeOil, ChangeTypes, Refuel});
    
    방법 PitStop은 더욱 확장성이 있다.그것은 쉽게 확장되어 거의 수정할 필요가 없다.이것은 간단하게 실행할 함수를 매개 변수로 전달함으로써 실현된 것으로 그것들을 일등 공민으로 간주한다.

    이제 선종을 안으러 가자, 동료들아.


    좋은 웹페이지 즐겨찾기