수색…


기능과 행동

Func 은 매개 변수화 된 익명 함수의 소유자를 제공합니다. 주요 유형은 입력이고 마지막 유형은 항상 리턴 값입니다.

// square a number.
Func<double, double> square = (x) => { return x * x; };

// get the square root.
// note how the signature matches the built in method.
Func<double, double> squareroot = Math.Sqrt;

// provide your workings.
Func<double, double, string> workings = (x, y) => 
    string.Format("The square of {0} is {1}.", x, square(y))

액션 객체는 void 메소드와 비슷하므로 입력 유형 만 있습니다. 평가 스택에는 결과가 없습니다.

// right-angled triangle.
class Triangle
{
    public double a;
    public double b;
    public double h;
}

// Pythagorean theorem.
Action<Triangle> pythagoras = (x) => 
    x.h = squareroot(square(x.a) + square(x.b));

Triangle t = new Triangle { a = 3, b = 4 };
pythagoras(t);
Console.WriteLine(t.h); // 5.

불변성

이터 빌리티는 함수형 프로그래밍에서는 일반적이며 객체 지향 프로그래밍에서는 드물다.

예를 들어 변경 가능한 상태의 주소 유형을 만듭니다.

public class Address () 
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City  { get; set; }
}

코드 조각은 위 개체의 속성을 변경할 수 있습니다.

이제 불변의 주소 유형을 작성하십시오.

public class Address () 
{
    public readonly string Line1;
    public readonly string Line2;
    public readonly string City;

    public Address(string line1, string line2, string city) 
    {
        Line1 = line1;
        Line2 = line2;
        City  = city;
    }
}

읽기 전용 모음을 갖고있는 것이 불변성을 존중하지 않는다는 것을 명심하십시오. 예를 들어,

public class Classroom
{
    public readonly List<Student> Students;
    
    public Classroom(List<Student> students)
    {
        Students = students;
    }
}

객체의 사용자가 콜렉션을 변경할 수 있기 때문에 변경 불가능합니다 (요소를 추가하거나 제거 할 수 있음). 불변으로 만들려면 IEnumerable과 같은 인터페이스를 사용해야합니다. IEnumerable은 추가 할 메소드를 공개하지 않으며 ReadOnlyCollection으로 만듭니다.

public class Classroom
{
    public readonly ReadOnlyCollection<Student> Students;

    public Classroom(ReadOnlyCollection<Student> students)
    {
        Students = students;
    }
}

List<Students> list = new List<Student>();
// add students
Classroom c = new Classroom(list.AsReadOnly());   

불변 객체를 사용하면 다음과 같은 이점이 있습니다.

  • 그것은 알려진 상태에있을 것입니다 (다른 코드는 변경할 수 없습니다).
  • 스레드로부터 안전합니다.
  • 생성자는 유효성 검사를위한 단일 장소를 제공합니다.
  • 객체를 변경할 수 없다는 것을 알고 있으면 코드를 더 쉽게 이해할 수 있습니다.

Null 참조 피하기

C # 개발자는 많은 null 참조 예외를 처리해야합니다. F # 개발자는 Option 유형을 가지고 있기 때문에 개발자가 아닙니다. Option <> 유형 (일부는 <>을 이름으로 선호 함)은 Some 및 None 반환 유형을 제공합니다. 메소드가 널 (NULL) 레코드를 리턴하려고 할 수 있음을 명시 적으로 나타냄니다.

예를 들어, 다음을 읽고 널 값을 처리해야하는지 알 수 없습니다.

var user = _repository.GetUser(id);

가능한 null에 대해 알고 있다면이를 처리 할 상용구 코드를 도입 할 수 있습니다.

var username = user != null ? user.Name : string.Empty;

Option <>이 대신 반환되면 어떻게됩니까?

Option<User> maybeUser = _repository.GetUser(id);

이제 코드에서 None 레코드가 반환되고 Some 또는 None을 확인하는 상용구 코드가 필요하다는 것을 명시합니다.

var username = maybeUser.HasValue ? maybeUser.Value.Name : string.Empty;

다음 메서드는 Option <>을 반환하는 방법을 보여줍니다.

public Option<User> GetUser(int id)
{
    var users = new List<User>
    {
        new User { Id = 1, Name = "Joe Bloggs" },
        new User { Id = 2, Name = "John Smith" }
    };

    var user = users.FirstOrDefault(user => user.Id == id);

    return user != null ? new Option<User>(user) : new Option<User>();
}

다음은 Option <>의 최소 구현입니다.

public struct Option<T>
{
    private readonly T _value;

    public T Value
    {
        get
        {
            if (!HasValue)
                throw new InvalidOperationException();

            return _value;
        }
    }

    public bool HasValue
    {
        get { return _value != null; }
    }

    public Option(T value)
    {
        _value = value;
    }

    public static implicit operator Option<T>(T value)
    {
        return new Option<T>(value);
    }
}

위의 설명을 위해 avoidNull.csx 는 C # REPL을 사용하여 실행할 수 있습니다.

명시된 바와 같이, 이것은 최소한의 구현입니다. "어쩌면"NuGet 패키지를 검색하면 여러 좋은 라이브러리를 얻을 수 있습니다.

고차 함수

고차 함수는 다른 함수를 인수로 사용하거나 함수를 반환하는 함수입니다.

이것은 LINQ Where 절에 조건자를 전달할 때와 같이 lambda를 사용하여 일반적으로 수행됩니다.

var results = data.Where(p => p.Items == 0);

Where () 절은 상당한 유연성을 제공하는 많은 다른 술어를받을 수 있습니다.

메소드를 다른 메소드로 전달하는 것은 전략 디자인 패턴을 구현할 때도 나타납니다. 예를 들어, 런타임시 요구 사항에 따라 다양한 Sorting 메서드를 선택하여 개체의 Sort 메서드에 전달할 수 있습니다.

불변의 콜렉션

System.Collections.Immutable NuGet 패키지는 불변의 컬렉션 클래스를 제공합니다.

항목 생성 및 추가하기

var stack = ImmutableStack.Create<int>();
var stack2 = stack.Push(1); // stack is still empty, stack2 contains 1
var stack3 = stack.Push(2); // stack2 still contains only one, stack3 has 2, 1

빌더를 사용하여 만들기

특정 불변의 콜렉션에는 큰 불변 인스턴스를 저렴하게 구축하는 데 사용할 수있는 Builder 내부 클래스가 있습니다.

var builder = ImmutableList.CreateBuilder<int>(); // returns ImmutableList.Builder
builder.Add(1);
builder.Add(2);
var list = builder.ToImmutable();

기존 IEnumerable에서 만들기

var numbers = Enumerable.Range(1, 5);
var list = ImmutableList.CreateRange<int>(numbers);

모든 불변의 콜렉션 유형 목록 :



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow