C#7 기능 코드 예제를 살펴보세요:
튜플 값 유형
.NET에서는 튜플 형식을 제공하지만 이를 C#에서 사용하면 다양한 문제가 발생합니다. 튜플 유형은 참조 유형이므로 성능에 민감한 일부 코드에서 이를 사용하는 데 따른 GC 오버헤드를 피할 수 있습니다. 동시에, 튜플 유형은 불변이며, 이는 스레드 간 공유를 더욱 안전하게 만드는 동시에 변경이 이루어질 때마다 새 객체를 할당해야 함을 의미합니다.
이 문제를 해결하기 위해 C# 7에서는 값 유형의 튜플을 제공합니다. 이는 변경 가능한 유형으로, 성능을 중시하는 코드에 더 효율적입니다. 또한 값형으로서 할당될 때마다 복사본을 생성하므로 멀티스레딩 문제가 발생할 위험이 거의 없습니다.
다음 구문을 사용하여 튜플을 생성할 수 있습니다:
var result = (5, 20);
튜플의 값에 이름을 지정하도록 선택할 수도 있습니다. 이는 필수는 아니지만 코드를 더 읽기 쉽게 만듭니다.
아아아아"훌륭한 기능이지만 직접 작성할 수 있습니다."라고 생각할 수도 있습니다. 하지만 다음 기능이 하이라이트입니다.
여러 반환 값
C와 같은 언어에서는 함수에서 두 개의 값을 반환하는 것이 항상 번거롭습니다. 결과를 일부 구조로 캡슐화하거나 출력 매개변수를 사용하도록 선택할 수만 있습니다. 많은 함수형 프로그래밍 언어와 마찬가지로 C#은 이 기능을 제공하는 첫 번째 방법인
var result = (count: 5, sum: 20);
를 선택합니다. 보시다시피 여기서 일반 튜플을 사용하는 데에는 기본적인 문제가 있습니다. 즉, 각 필드가 무엇을 하는지 알 수 있는 방법이 없습니다. 따라서 C#에서는 컴파일러 트릭을 통해 결과 이름을
(int, int) Tally (IEnumerable<int> list)
로 지정합니다. 여기서 한 가지 점을 강조해야 합니다. C#은 새로운 익명 형식을 생성하지 않습니다. 얻는 것은 여전히 튜플이지만 컴파일러는 해당 속성이 Item1 및 Item2 대신 Count 및 Sum이라고 가정합니다. 따라서 다음 코드 줄은 동일합니다.
(int Count, int Sum) Tally (IEnumerable<int> list)
아직 다중 할당 구문이 없다는 점에 유의하세요. 이 구문이 최종적으로 구현되면 그 사용법은 다음과 같을 것입니다:
var result = Tally(list); Console.WriteLine(result.Item1); Console.WriteLine(result.Count);
간단한 기능적 기능을 제공하는 것 외에도 비동기 함수에서는 out 매개변수가 허용되지 않기 때문에 다중 반환 값의 유용성은 비동기 코드 작성에도 반영됩니다.
패턴 일치: 향상된 Switch 구문 블록
C#에 대한 VB 및 기능적 프로그래머의 가장 일반적인 불만은 C#의 스위치 문의 기능이 매우 제한적이라는 것입니다. VB 개발자는 범위 일치를 원하고, F# 또는 Haskell에 익숙한 개발자는 분해된 패턴 일치를 사용할 수 있기를 원합니다. C#에서는 두 기능을 모두 제공할 예정입니다.
패턴이 유형과 일치할 때 캐스트 결과를 보관할 변수를 만들 수 있습니다. 예를 들어 System.Object에서 switch 문을 사용하는 경우 다음 코드를 작성할 수 있습니다.
(count, sum) = Tally(list);
객체가 숫자 유형인 경우 변수 x에 값이 할당됩니다. 그렇지 않으면 프로그램은 위에서 아래로 다음 사례 설명 블록을 확인합니다. 일치 항목을 더 구체적으로 지정하려면 범위 확인을 사용할 수도 있습니다.
case int x:
이 예에서 객체가 양의 정수이면 x 코드 블록이 실행됩니다. 객체가 0이거나 음의 정수이면 y 코드 블록이 실행됩니다.
null 값을 확인해야 하는 경우 다음 구문을 사용하세요.
case int x when x > 0: case int y:
패턴 매칭: 분해
지금까지 우리는 VB의 기존 기능에 대한 몇 가지 점진적인 개선만을 보여 주었습니다. 패턴 일치의 진정한 힘은 객체를 완전히 분리할 수 있는 분해에 있습니다.
case null;
이 코드는 두 가지 작업을 수행합니다.
지역 변수 s를 생성하고 ((교수)사람).Subject 값을 할당합니다.
동등성 검사를 수행합니다 ((Professor)person).FirstName == "Scott".
C# 6 코드로 다시 작성하면 다음과 같습니다:
if (person is Professor {Subject is var s, FirstName is "Scott"})
최종 릴리스에서는 스위치 블록에 대한 두 가지 개선 사항이 모두 나타날 것으로 예상됩니다.
참고반환
큰 데이터 구조를 참조로 전달하는 것은 전체 구조의 복사본이 필요한 값으로 전달하는 것보다 훨씬 빠릅니다. 마찬가지로 대규모 데이터 구조에 대한 참조를 반환하면 속도도 향상될 수 있습니다.
C와 같은 언어에서는 포인터를 통해 구조체에 대한 참조를 반환할 수 있습니다. 이 접근 방식은 일반적인 문제를 야기합니다. 즉, 포인터가 가리키는 메모리가 어떤 이유로 회수되었을 수 있습니다.
C#에서는 규칙이 연결된 포인터인 참조를 사용하여 이 문제를 방지합니다. 가장 중요한 규칙은 지역 변수에 대한 참조를 반환할 수 없다는 것입니다. 이렇게 하면 함수가 반환될 때 변수가 참조하는 스택 정보에 액세스할 수 없게 됩니다.
在微软的展示代码中,它所返回的引用指向一个数组中的某个结构。由于它实质上是指向数组中某个元素的指针,因此随后可以对数组本身进行修改。举例来说:
var x = ref FirstElement(myArray) x = 5; //MyArray[0] now equals 5
这一语法的用例是对性能高度敏感的代码,在大多数应用中都无需使用这一特性。
二进制字面值(Binary Literals)
此次发布还引入了一个小特性,即二进制字面值。这一语法只是一个简单的前缀而已,例如5可以表示为“0b0101”。这一特性的主要用例是设置基于flag的枚举,以及创建位掩码(bitmask),以用于与C风格语言的互操作。
本地函数
本地函数是指在另一个函数中所定义的函数。第一眼看来,本地函数似乎只是比匿名函数稍好的一种语法。但它实际上还存在几个优点:
首先,你无需为其分配一个委托以保存该函数。这不仅减少了内存压力,同时还允许编译器对该函数进行内联操作。
其次,在创建闭包时,也无需为其分配一个对象,因为它能够直接访问本地变量。这一点同样能够改善性能,因为它也减少了GC的压力。
按照第二条规则推算,你将无法创建一个指向本地函数的委托。这一点对于代码的组织其实是一个优点,因为你无需创建独立的函数,并且将现有函数的状态作为显式的参数进行传递。
部分类的改进
最后演示的特性是一种处理部分类的新方式。在过去,部分类的应用是基于代码生成优先的概念而出现的。所生成的代码将包含一系列部分方法,开发者可以选择实现这些方法,以调整类的行为。
通过新的“replace”语法,开发者就多了一种新选择,能够以最直接的方式编写代码,随后再引入代码生成器,并重写这些方法。以下将通过一个简单的示例表现开发者的代码编写方式:
public string FirstName {get; set;}
简单又清晰,但完全不符合XAML风格应用的写法。因此,代码生成器将生成如下代码:
private string m_FirstName; static readonly PropertyChangedEventArgs s_FirstName_EventArgs =new PropertyChangedEventArgs("FirstName") replace public string FirstName { get { return m_FirstName; } set { if (m_FirstName == value) return; m_FirstName = value; PropertyChanged?.Invoke(this, m_FirstName_EventArg); }
通过“replace”关键字,所生成的代码将直接替换手写的代码,添加所缺失的功能。在这个示例中,我们甚至还能够处理一些开发者经常会忽略的麻烦的部分,例如对EventArgs对象进行缓存。
虽然这个官方示例仅用于属性变更通知,但这一技术还可用于各种“面向切面编程(AOP)”的场景,例如在代码中注入日志记录、安全检查、参数校验以及其他各种繁琐的样板式代码。
如果读者想实际了解一下这些特性,可以观赏Channel 9中的视频“The Future of C#”。
위 내용은 C#7 기능 코드 예제를 살펴보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!