C#6 새 기능 개요C# 6 New Features Overview

최신 버전의를 C# – 버전 6 – 언어 상용구를 덜, 향상 된 이해를 돕기 위해 자세한 일관성 있고 언어 진화 계속 합니다. 클리너 초기화 구문을 사용 하는 기능 catch/finally 블록 및 null 조건부 await? 연산자는 특히 유용 합니다.The latest version of the C# language – version 6 – continues to evolve the language to have less boilerplate, improved clarity, and more consistency. Cleaner initialization syntax, the ability to use await in catch/finally blocks, and the null-conditional ? operator are especially useful.

이 문서에서는의 새로운 기능을 소개 C# 6.This document introduces the new features of C# 6. Mono 컴파일러에서 완전히 지원 됩니다 및 새로운 기능을 사용 하 여 모든 Xamarin 대상 플랫폼에서 개발자가 시작할 수 있습니다.It is fully supported by the mono compiler and developers can start using the new features across all the Xamarin target platforms.

새로운 기능 C# 6 비디오What's new in C# 6 video

사용 하 여 C# 6Using C# 6

C# 6 컴파일러는 모든 최신 버전의 Visual Studio for macThe C# 6 compiler is used in all recent versions of Visual Studio for Mac. 명령줄 컴파일러를 사용 하 여 확인 해야 mcs --version 4.0 이상 반환 합니다.Those using command-line compilers should confirm that mcs --version returns 4.0 or higher. Mac 사용자 용 visual Studio에서 참조 하 여 Mono 4 이상이 있는 경우 설치를 확인할 수 있습니다 Mac 용 Visual Studio에 대 한 > Mac 용 Visual Studio > 자세한 정보 표시합니다.Visual Studio for Mac users can check if they have Mono 4 (or newer) installed by referring to About Visual Studio for Mac > Visual Studio for Mac > Show Details.

상용구를 덜Less Boilerplate

using staticusing static

열거형과 같은 특정 클래스 System.Math, 정적 값 및 함수의 소유자 주로 됩니다.Enumerations, and certain classes such as System.Math, are primarily holders of static values and functions. C# 6, 단일을 사용 하 여 형식의 모든 정적 멤버를 가져올 수 있습니다 using static 문입니다.In C# 6, you can import all static members of a type with a single using static statement. 일반적인 삼각 함수를 비교 C# 5 및 C# 6:Compare a typical trigonometric function in C# 5 and C# 6:

// Classic C#
class MyClass
{
    public static Tuple<double,double> SolarAngleOld(double latitude, double declination, double hourAngle)
    {
        var tmp = Math.Sin (latitude) * Math.Sin (declination) + Math.Cos (latitude) * Math.Cos (declination) * Math.Cos (hourAngle);
        return Tuple.Create (Math.Asin (tmp), Math.Acos (tmp));
    }
}

// C# 6
using static System.Math;

class MyClass
{
    public static Tuple<double, double> SolarAngleNew(double latitude, double declination, double hourAngle)
    {
        var tmp = Asin (latitude) * Sin (declination) + Cos (latitude) * Cos (declination) * Cos (hourAngle);
        return Tuple.Create (Asin (tmp), Acos (tmp));
    }
}

using static 공용 해도 const 같은 필드 Math.PIMath.E직접 액세스할 수 있는:using static does not make public const fields, such as Math.PI and Math.E, directly accessible:

for (var angle = 0.0; angle <= Math.PI * 2.0; angle += Math.PI / 8) ... 
//PI is const, not static, so requires Math.PI

정적 확장 메서드를 사용 하 여 사용 하 여using static with Extension Methods

using static 시설 약간 다르게 작동 확장 메서드를 사용 하 여 합니다.The using static facility operates a little differently with extension methods. 확장 메서드를 사용 하 여 작성 됩니다 static, 쉽게 작동 하는 데 기반이 인스턴스 없이도 이해 하지 않습니다.Although extension methods are written using static, they don’t make sense without an instance on which to operate. 경우에 따라서 using static 확장 메서드를 해당 대상 형식에서 사용할 수 있게 확장 메서드를 정의 하는 형식과 함께 사용 됩니다 (메서드의 this 형식).So when using static is used with a type that defines extension methods, the extension methods become available on their target type (the method's this type). 예를 들어 using static System.Linq.Enumerable 의 API 확장을 사용할 수 있습니다 IEnumerable<T> 모든 LINQ 형식에 표시 하지 않고 개체:For instance, using static System.Linq.Enumerable can be used to extend the API of IEnumerable<T> objects without bringing in all of the LINQ types:

using static System.Linq.Enumerable;
using static System.String;

class Program
{
    static void Main()
    {
        var values = new int[] { 1, 2, 3, 4 };
        var evenValues = values.Where (i => i % 2 == 0);
        System.Console.WriteLine (Join(",", evenValues));
    }
}

동작의 차이점을 설명 하는 이전 예제: 확장 메서드 Enumerable.Where 정적 메서드에 배열과 사용 하 여 연결 String.Join 에 대 한 참조 없이 호출할 수는 String 형식입니다.The previous example demonstrates the difference in behavior: the extension method Enumerable.Where is associated with the array, while the static method String.Join can be called without reference to the String type.

nameof 식nameof Expressions

참조 하려는 경우에 따라 이름에는 변수 또는 필드를 지정 했습니다.Sometimes, you want to refer to the name you’ve given a variable or field. C# 6 nameof(someVariableOrFieldOrType) 문자열을 반환 합니다 "someVariableOrFieldOrType"합니다.In C# 6, nameof(someVariableOrFieldOrType) will return the string "someVariableOrFieldOrType". 예를 들어 throw 할 때를 ArgumentException 가능성이 매우는 인수가 잘못 되었습니다. 이름을 지정 하려고 합니다.For instance, when throwing an ArgumentException you’re very likely to want to name which argument is invalid:

throw new ArgumentException ("Problem with " + nameof(myInvalidArgument))

주된 장점은 nameof 식 되는 형식을 확인 하 고 있다는 리팩터링 도구 기반과 호환 됩니다.The chief advantage of nameof expressions is that they are type-checked and are compatible with tool-powered refactoring. 형식 검사의 nameof 식을 상황에서 특히 시작 됩니다. 여기서는 string 형식을 동적으로 연결할 때 사용 됩니다.The type-checking of nameof expressions is particularly welcome in situations where a string is used to dynamically associate types. 예를 들어 iOS에에서는 string 프로토타입에 사용 된 유형을 지정 하는 데 사용 됩니다 UITableViewCell 개체는 UITableView합니다.For instance, in iOS a string is used to specify the type used to prototype UITableViewCell objects in a UITableView. nameof 이 연결 맞춤법 오류 또는 불량 리팩터링 하지 없도록 보장할 수 있습니다.nameof can assure this association does not fail due to a misspelling or sloppy refactoring:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell (nameof(CellTypeA), indexPath);
    cell.TextLabel.Text = objects [indexPath.Row].ToString ();
    return cell;
}

정규화 된 이름을 전달할 수 있지만 nameof, 마지막 요소에만 (마지막 .)이 반환 됩니다.Although you can pass a qualified name to nameof, only the final element (after the last .) is returned. 예를 들어 데이터 바인딩을 Xamarin.Forms에 추가할 수 있습니다.For instance, you can add a data binding in Xamarin.Forms:

var myReactiveInstance = new ReactiveType ();
var myLabelOld.BindingContext = myReactiveInstance;
var myLabelNew.BindingContext = myReactiveInstance;
var myLabelOld.SetBinding (Label.TextProperty, "StringField");
var myLabelNew.SetBinding (Label.TextProperty, nameof(ReactiveType.StringField));

두 호출 SetBinding 동일한 값을 전달 하는: nameof(ReactiveType.StringField) 됩니다 "StringField"아니라 "ReactiveType.StringField" 처음 예상한 대로입니다.The two calls to SetBinding are passing identical values: nameof(ReactiveType.StringField) is "StringField", not "ReactiveType.StringField" as you might initially expect.

Null 조건부 연산자Null-conditional Operator

이전 업데이트를 C# nullable 형식 및 null 병합 연산자의 개념을 도입 ?? nullable 값을 처리 하는 경우 상용구 코드 양을 줄일 수 있습니다.Earlier updates to C# introduced the concepts of nullable types and the null-coalescing operator ?? to reduce the amount of boilerplate code when handling nullable values. C#6이이 테마 "null 조건부 연산자"를 사용 하 여 계속 ?.합니다.C# 6 continues this theme with the "null-conditional operator" ?.. 개체가 없는 경우 null 조건부 연산자 멤버 값을 반환 식의 오른쪽에 있는 개체를 사용 하면 nullnull 그렇지 않은 경우:When used on an object on the right-hand side of an expression, the null-conditional operator returns the member value if the object is not null and null otherwise:

var ss = new string[] { "Foo", null };
var length0 = ss [0]?.Length; // 3
var length1 = ss [1]?.Length; // null
var lengths = ss.Select (s => s?.Length ?? 0); //[3, 0]

(둘 다 length0 하 고 length1 형식으로 유추 됩니다 int?)(Both length0 and length1 are inferred to be of type int?)

에서는 이전 예제에서 마지막 줄을 ? null 조건부 연산자와 함께에서 ?? null 병합 연산자입니다.The last line in the previous example shows the ? null-conditional operator in combination with the ?? null-coalescing operator. 새 C# 6 null 조건부 연산자 반환 null 이때 null 병합 연산자로 시작 되 고 제공 하는 0 일 경우 배열의 두 번째 요소에는 lengths (여부는 적합 하지 인 물론 배열 문제에 따라 다름).The new C# 6 null-conditional operator returns null on the 2nd element in the array, at which point the null-coalescing operator kicks in and supplies a 0 to the lengths array (whether that's appropriate or not is, of course, problem-specific).

Null 조건부 연산자 단시간 상용구 많은 응용 프로그램에 필요한 null 검사의 양을 줄여야 합니다.The null-conditional operator should tremendously reduce the amount of boilerplate null-checking necessary in many, many applications.

Null 조건부 연산자 모호성으로 인해 일부 제한이 있습니다.There are some limitations on the null-conditional operator due to ambiguities. 즉시를 따를 수 없습니다는 ? 괄호로 묶인 인수 목록이 있는 때 가장 큰 대리자를 사용 하 여 수행 합니다.You cannot immediately follow a ? with a parenthesized argument list, as you might hope to do with a delegate:

SomeDelegate?("Some Argument") // Not allowed

그러나 Invoke 구분 하는 데 사용할 수는 ? 인수 목록에서 통해는 여전히 표시 된 향상 된 기능 및를 null-상용구 블록 검사:However, Invoke can be used to separate the ? from the argument list and is still a marked improvement over a null-checking block of boilerplate:

public event EventHandler HandoffOccurred;
public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    HandoffOccurred?.Invoke (this, userActivity.UserInfo);
    return true;
}

문자열 보간String Interpolation

String.Format 함수는 일반적으로 인덱스 자리 표시자로 사용 형식 문자열의 예를 들어 String.Format("Expected: {0} Received: {1}.", expected, received).The String.Format function has traditionally used indices as placeholders in the format string, e.g., String.Format("Expected: {0} Received: {1}.", expected, received). 물론, 새 값 추가 인수를 계산 하 고 자리 표시자를 번호 다시 매기기 인수 목록에서 올바른 시퀀스에서 새 인수 삽입 성가신 거의 작업을 관련 항상 했습니다.Of course, adding a new value has always involved an annoying little task of counting up arguments, renumbering placeholders, and inserting the new argument in the right sequence in the argument list.

C#6의 새로운 특징 문자열 보간 기능을 크게 향상 String.Format합니다.C# 6's new string interpolation feature greatly improves upon String.Format. 변수 접두사로 문자열에서 직접 이름을 지정할 수는 이제는 $합니다.Now, you can directly name variables in a string prefixed with a $. 예를 들면 다음과 같습니다.For instance:

$"Expected: {expected} Received: {received}."

변수 물론, 체크 인 되 고 철자가 잘못 되었거나, 사용할 수 없는 변수 컴파일러 오류가 발생 합니다.Variables are, of course, checked and a misspelled or non-available variable will cause a compiler error.

자리 표시자를 단순 변수를 사용할 필요가 없습니다, 식일 수 있습니다.The placeholders do not need to be simple variables, they can be any expression. 이러한 자리 표시자 내의 따옴표를 사용할 수 있습니다 없이 해당 따옴표를 이스케이프 합니다.Within these placeholders, you can use quotation marks without escaping those quotations. 예를 들어 확인 된 "s" 다음에서:For instance, note the "s" in the following:

var s = $"Timestamp: {DateTime.Now.ToString ("s", System.Globalization.CultureInfo.InvariantCulture )}"

문자열 보간 맞춤 및 서식 지정 구문을 지원 String.Format합니다.String interpolation supports the alignment and formatting syntax of String.Format. 이전에 작성 하듯이 {index, alignment:format}, C# 작성 하는 6 {placeholder, alignment:format}:Just as you previously wrote {index, alignment:format}, in C# 6 you write {placeholder, alignment:format}:

using static System.Linq.Enumerable;
using System;

class Program
{
    static void Main ()
    {
        var values = new int[] { 1, 2, 3, 4, 12, 123456 };
        foreach (var s in values.Select (i => $"The value is { i,10:N2}.")) {
            Console.WriteLine (s);
        }
    Console.WriteLine ($"Minimum is { values.Min(i => i):N2}.");
    }
}

결과:results in:

The value is       1.00.
The value is       2.00.
The value is       3.00.
The value is       4.00.
The value is      12.00.
The value is 123,456.00.
Minimum is 1.00.

문자열 보간은에 대 한 syntactic sugar String.Format: 함께 사용할 수 없습니다 @"" 문자열 리터럴 및와 호환 되지 않습니다 const자리 표시 자가 되는 경우에:String interpolation is syntactic sugar for String.Format: it cannot be used with @"" string literals and is not compatible with const, even if no placeholders are used:

const string s = $"Foo"; //Error : const requires value

문자열 보간 사용 하 여 함수 인수를 구축 하는 일반적인 사용 사례에서 이스케이프, 인코딩 및 문화권 문제에 대해 주의 해야 합니다.In the common use-case of building function arguments with string interpolation, you still need to be careful about escaping, encoding, and culture issues. SQL 쿼리와 URL 인 물론, 삭제 하는 데 중요 합니다.SQL and URL queries are, of course, critical to sanitize. 와 마찬가지로 String.Format, 문자열 보간을 사용 하는 CultureInfo.CurrentCulture합니다.As with String.Format, string interpolation uses the CultureInfo.CurrentCulture. 사용 하 여 CultureInfo.InvariantCulture 좀 더 단어는:Using CultureInfo.InvariantCulture is a little more wordy:

Thread.CurrentThread.CurrentCulture  = new CultureInfo ("de");
Console.WriteLine ($"Today is: {DateTime.Now}"); //"21.05.2015 13:52:51"
Console.WriteLine ($"Today is: {DateTime.Now.ToString(CultureInfo.InvariantCulture)}"); //"05/21/2015 13:52:51"

초기화Initialization

C#6에는 다양 한 속성, 필드 및 멤버를 지정 하는 간단한 방법 제공 합니다.C# 6 provides a number of concise ways to specify properties, fields, and members.

Auto 속성 초기화Auto-property Initialization

Auto 속성 필드와 동일한 간결한 방식으로 초기화 될 수 있습니다.Auto-properties can now be initialized in the same concise manner as fields. 변경할 수 없는 auto 속성 getter만을 사용 하 여 작성할 수 있습니다.Immutable auto-properties can be written with only a getter:

class ToDo
{
    public DateTime Due { get; set; } = DateTime.Now.AddDays(1);
    public DateTime Created { get; } = DateTime.Now;

생성자에는 getter 전용 auto 속성의 값을 설정할 수 있습니다.In the constructor, you can set the value of a getter-only auto-property:

class ToDo
{
    public DateTime Due { get; set; } = DateTime.Now.AddDays(1);
    public DateTime Created { get; } = DateTime.Now;
    public string Description { get; }

    public ToDo (string description)
    {
        this.Description = description; //Can assign (only in constructor!)
    }

Auto 속성이 초기화가 일반적인 공간 절약 기능 및 해당 개체의 불변성을 강조 하기 위해 개발자에 게 유용 하 게 됩니다.This initialization of auto-properties is both a general space-saving feature and a boon to developers wishing to emphasize immutability in their objects.

인덱스 이니셜라이저Index Initializers

C#6은 인덱서가 있는 형식에 키와 값을 설정할 수 있도록 하는 인덱스 이니셜라이저를 소개 합니다.C# 6 introduces index initializers, which allow you to set both the key and value in types that have an indexer. 에 대 한 일반적으로 이것이 Dictionary-데이터 구조를 스타일:Typically, this is for Dictionary-style data structures:

partial void ActivateHandoffClicked (WatchKit.WKInterfaceButton sender)
{
    var userInfo = new NSMutableDictionary {
        ["Created"] = NSDate.Now,
        ["Due"] = NSDate.Now.AddSeconds(60 * 60 * 24),
        ["Task"] = Description
    };
    UpdateUserActivity ("com.xamarin.ToDo.edit", userInfo, null);
    statusLabel.SetText ("Check phone");
}

식 본문 함수 멤버Expression-bodied Function Members

람다 함수에는 그 중 하나는 공간 저장 하 여 몇 가지 이점을 있습니다.Lambda functions have several benefits, one of which is simply saving space. 클래스 식 본문 멤버를 이전 버전의 보다 좀 더 간결 하 게 표현할 수 있는 작은 함수를 허용 하는 마찬가지로, C# 6.Similarly, expression-bodied class members allow small functions to be expressed a little more succinctly than was possible in previous versions of C# 6.

식 본문 함수 멤버는 기존의 블록 구문이 아니라 람다 화살표 구문을 사용합니다.Expression-bodied function members use the lambda arrow syntax rather than the traditional block syntax:

public override string ToString () => $"{FirstName} {LastName}";

람다 화살표 구문을 사용 하지 않음을 명시적 알림 return합니다.Notice that the lambda-arrow syntax does not use an explicit return. 반환 하는 함수에 대 한 void, 식 문을 수도 있어야 합니다.For functions that return void, the expression must also be a statement:

public void Log(string message) => System.Console.WriteLine($"{DateTime.Now.ToString ("s", System.Globalization.CultureInfo.InvariantCulture )}: {message}");

식 본문 멤버 규칙이 계속 적용 됩니다는 async 메서드 하지만 속성이 아니라 지원 됩니다.Expression-bodied members are still subject to the rule that async is supported for methods but not properties:

//A method, so async is valid
public async Task DelayInSeconds(int seconds) => await Task.Delay(seconds * 1000);
//The following property will not compile
public async Task<int> LeisureHours => await Task.FromResult<char> (DateTime.Now.DayOfWeek.ToString().First()) == 'S' ? 16 : 5;

예외Exceptions

에 대 한 없는 두 가지 방법으로: 예외 처리 이해 하기 어렵습니다.There's no two ways about it: exception-handling is hard to get right. 새로운 기능 C# 6 보다 유연 하 고 일관 된 예외 처리를 확인 합니다.New features in C# 6 make exception-handling more flexible and consistent.

예외 필터Exception Filters

정의상, 특수 한 상황에서 예외가 발생 하 고 이유 및 방법에 대 한 코드는 매우 어려울 수 있습니다 모든 특정 유형의 예외가 발생 하는 방법입니다.By definition, exceptions occur in unusual circumstances, and it can be very difficult to reason and code about all the ways an exception of a particular type might occur. C#6은 런타임 평가 필터를 사용 하 여 실행 처리기를 보호 하는 기능을 소개 합니다.C# 6 introduces the ability to guard an execution handler with a runtime-evaluated filter. 추가 하 여 이렇게를 when (bool) 법선 후 패턴 catch(ExceptionType) 선언 합니다.This is done by adding a when (bool) pattern after the normal catch(ExceptionType) declaration. 다음에서 필터는와 관련 된 구문 분석 오류를 구별 합니다 date 다른 구문 분석 오류와 달리 매개 변수입니다.In the following, a filter distinguishes a parse error relating to the date parameter as opposed to other parsing errors.

public void ExceptionFilters(string aFloat, string date, string anInt)
{
    try
    {
        var f = Double.Parse(aFloat);
        var d = DateTime.Parse(date);
        var n = Int32.Parse(anInt);
    } catch (FormatException e) when (e.Message.IndexOf("DateTime") > -1) {
        Console.WriteLine ($"Problem parsing \"{nameof(date)}\" argument");
    } catch (FormatException x) {
        Console.WriteLine ("Problem parsing some other argument");
    }
}

... catch에서 await를 마지막으로 하는 중...await in catch...finally…

합니다 async 에 도입 된 기능 C# 5 언어용 판도 되었습니다.The async capabilities introduced in C# 5 have been a game-changer for the language. C# 5 await 에서 허용 되지 않았습니다 catchfinally 블록의 값을 지정 하는 불편 합니다 async/await 기능.In C# 5, await was not allowed in catch and finally blocks, an annoyance given the value of the async/await capability. C#6에는 비동기 결과 다음 코드 조각에 나와 있는 것 처럼 프로그램을 통해 지속적으로 대기할 수 있도록 이러한 제한을 제거 합니다.C# 6 removes this limitation, allowing asynchronous results to be awaited consistently through the program as shown in the following snippet:

async void SomeMethod()
{
    try {
        //...etc...
    } catch (Exception x) {
        var diagnosticData = await GenerateDiagnosticsAsync (x);
        Logger.log (diagnosticData);
    } finally {
        await someObject.FinalizeAsync ();
    }
}

요약Summary

C# 언어 진화 또한 모범 사례를 홍보 하 고 도구를 지원 하는 동안 개발자 생산성을 확인 하 여 계속 합니다.The C# language continues to evolve to make developers more productive while also promoting good practices and supporting tooling. 이 문서에 새 언어 기능의 개요를 지정 하는 C# 6 및 사용 방법에 대해 간략하게 설명 했습니다.This document has given an overview of the new language features in C# 6 and has briefly demonstrated how they are used.