C#7 機能コードの例を紹介します

黄舟
リリース: 2017-03-09 15:36:21
オリジナル
1432 人が閲覧しました

C#7 機能のコード例を紹介します:

タプル値の型

.NET ではタプル型が提供されていますが、これを C# で使用する場合にはさまざまな問題があります。タプル型は参照型であるため、パフォーマンス重視のコードで使用することによる GC オーバーヘッドをおそらく回避できます。同時に、タプル型は不変であるため、スレッド間での共有がより安全になりますが、変更が行われるたびに新しいオブジェクトを割り当てる必要があることも意味します。

この問題に対処するために、C# 7 では値の型のタプルが提供されます。これは可変型であり、パフォーマンスを重視するコードではより効率的です。また、値型として割り当てられるたびにコピーが作成されるため、マルチスレッドの問題が発生するリスクがほとんどありません。

次の構文を使用してタプルを作成できます:

var result = (5, 20);
ログイン後にコピー

タプル内の値に名前を付けることも選択できます。これは必須ではありませんが、コードが読みやすくなるだけです。

りー

「素晴らしい機能だけど、自分でも書ける」と思うかもしれません。しかし、次の機能がハイライトです。

複数の戻り値

C 系言語では、関数から 2 つの値を返すのは常に面倒です。選択できるのは、結果を何らかの構造にカプセル化するか、出力パラメーターを使用することだけです。多くの関数型プログラミング言語と同様に、C# はこの機能を提供する最初の方法を選択します:

var result = (count: 5, sum: 20);
ログイン後にコピー

ご覧のとおり、ここで汎用タプルを使用する場合には基本的な問題があります。各フィールドが何を行うのかを知る方法がありません。したがって、C# はコンパイラ トリックを使用して結果に次の名前を付けることを選択します:

(int, int) Tally (IEnumerable<int> list)
ログイン後にコピー

ここで 1 つの点を強調する必要があります。C# は新しい匿名型を生成しませんが、取得するものは依然としてタプルですが、コンパイラーはそのプロパティが Item1 と Items2 ではなく Count と Sum であると想定します。したがって、次のコード行は同等です:

(int Count, int Sum) Tally (IEnumerable<int> list)
ログイン後にコピー

複数の代入構文がまだないことに注意してください。この構文が最終的に実装された場合、その使用法は次のようになります:

var result = Tally(list);
Console.WriteLine(result.Item1);
Console.WriteLine(result.Count);
ログイン後にコピー

単純な関数関数を提供することに加えて、非同期関数では out パラメーターが許可されないため、複数の戻り値の有用性は非同期コードの作成にも反映されます。

パターン マッチング: Switch 構文ブロックの改善

VB や関数型プログラマーからの C# に関する最も一般的な苦情は、C# の switch ステートメントの機能が非常に制限されているというものです。 VB 開発者は範囲マッチングを実行できるようにしたいと考えていますが、F# や Haskell に慣れている開発者は、分解されたパターン マッチングを使用できるようにしたいと考えています。 C# は両方の機能を提供する予定です。

型のパターン マッチングを行う場合、キャストの結果を保持する変数を作成できます。たとえば、System.Object で switch ステートメントを使用する場合は、次のコードを記述できます:

(count, sum) = Tally(list);
ログイン後にコピー

オブジェクトが数値型の場合、変数 x には値が割り当てられます。それ以外の場合、プログラムは次の case ステートメント ブロックを上から下の順にチェックします。一致をより具体的にしたい場合は、範囲チェックを使用することもできます:

case int x:
ログイン後にコピー

この例では、オブジェクトが正の整数の場合、x コード ブロックが実行されます。オブジェクトが 0 または負の整数の場合、y コード ブロックが実行されます。

null 値をチェックする必要がある場合は、次の構文を使用してください:

case int x when x > 0:
case int y:
ログイン後にコピー

パターンマッチング: 分解

これまでのところ、VB の既存の機能に対するいくつかの段階的な改善のみを示してきました。パターン マッチングの真の力は、オブジェクトを完全に分解できる分解にあります。

case null;
ログイン後にコピー

という構文を考えてみましょう。 このコードは 2 つのことを実現します:

  1. ローカル変数 s を作成し、それに値 ((Professor)person).Subject を割り当てます。

  2. 等価性チェック ((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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート