タグ

ブックマーク / ufcpp.net (15)

  • 複合型の分解

    概要 Ver. 7 タプルから値を取り出す際には、メンバーを直接、それぞれバラバラに受け取りたくなることがあります。 「名前のない複合型」で説明したように、 メンバー名だけ見ればその型が何を意味するか分かるからこそ型に名前が付かないわけです。 このとき、その型を受け取る変数にも、よい名前が浮かばなくなるはずです。 そこでC# 7では、タプルと同時に、分解(deconstruction)のための構文が追加されました。 以下のような、整数列の個数(count)と和(sum)を同時に計算するメソッドがあったとします。 「名前のない複合型」で説明したように、 戻り値の型として「個数と和」みたいな名前(CountAndSumとか)しか思い浮かばないようなものです。 static (int count, int sum) Tally(IEnumerable<int> items) { var coun

    複合型の分解
    s_ryuuki
    s_ryuuki 2023/08/13
    任意の型を分解
  • JSON とかの中身確認ツール

    今日は、「主に自分が使う用ツールを Blazor WebAssembly で作って Static Web Apps に置いたよ」系の話を一応ブログ化。 ソースコード Static Web App よくある「JSON とかのデータの中身を確認するツール」です。 しばらく、JSON と MessagePack の読み書きをするコードを書いてて、 デバッグがしんどくなって作ったのがこのツール。 いろんな形式を同時に扱うことがニッチ需要なのであんまり自分の需要にあったツールがなかったんですよね。なら、まあ、自作。 こないだの C# 配信 で、UTF-8 とか MessagePack バイナリとかを手打ちで入力してたら @xin9le, @okazuki 両氏にドン引きされたやつ。 バイナリ読み込み (Parser) UTF-8 を ReadOnlySpan<byte> のまま扱ってて、 ブレイクポ

    JSON とかの中身確認ツール
  • Span<T>構造体

    概要 Ver. 7.2 Span<T>構造体(System名前空間)は、span (区間、範囲)という名前通り、連続してデータが並んでいるもの(配列など)の一定範囲を読み書きするために使う型です。 この型によって、ファイルの読み書きや通信などの際の、生データの読み書きがやりやすくなります。 生データの読み書きを直接行うことは少ないでしょうが、通信ライブラリなどを利用することで間接的にSpan<T>構造体のお世話になることはこれから多くなるでしょう。 Span<T>構造体は、 .NET Core 2.1 からは標準で入ります。それ以前のバージョンや、.NET Framework では、System.Memoryパッケージを参照することで利用できます。 C# 7.2の新機能のうちいくつかは、この型を効率的に・安全に使うために入ったものです。 そこで、言語機能に先立って、このSpan<T>構造体

    Span<T>構造体
    s_ryuuki
    s_ryuuki 2022/05/20
  • TargetFramework net5.0 なコードを .NET 6 ランタイムで動かす

    .NET のアップデート 昔の C# アプリ (例えば去年作った TargetFramework net5.0 なアプリ)をそのまま最新のランタイム(例えば .NET 6 ランタイム)で動かすことを考えます。 .NETAPI レベルでの破壊的変更はめったにないので、 「API が合わなくてロードできない」みたいな根的な問題はほぼ起こりません。 一方、挙動レベルでは時々破壊的変更があるんで、確実に動く保証はなかったりします。 (それでも、体感、9割方は動きますが。) ここ数バージョンであった影響がありそうな変更でいうと、 .NET Core 3.0 の頃同期 I/O が例外を出すようになったものがちらほらある ネットワークなどを介する場合、非同期でないとパフォーマンスが出ないので .NET 5 で、国際化対応に ICU を使うようになった 文字列の紹介順や、IndexOf の挙動がち

    TargetFramework net5.0 なコードを .NET 6 ランタイムで動かす
  • C# で、同じソースコードから常に同じバイナリを生成する

    昔、gist にだけ置いてて、そういえばブログに書いてなかったものを思い出したので書いておくことに。 (一応、部分的には言及したことがあるんですけど、ちゃんとした話はしたことがなかったはず。) 決定論的ビルド 3年くらい前まで、C# コードをコンパイルすると、ソースコードを一切書き換えていなくても、生成結果の exe/dll や pdb のバイナリが変化していました(決定性(deteminism)がない)。 原因は以下の2つです。 バイナリ中に埋め込まれる GUID にタイムスタンプと乱数から生成される値を使っていた デバッグ用のファイル情報がフルパスで埋め込まれていた GUID の方はタイムスタンプと乱数なので当に致命的で、ローカルで再コンパイルしても毎回バイナリが変化していました。 フルパスの方は基的には pdb (デバッグ用シンボル情報)だけの問題なんですが、 exe/dll で

    C# で、同じソースコードから常に同じバイナリを生成する
    s_ryuuki
    s_ryuuki 2021/03/31
  • readonly の注意点

    概要 「定数」で、読み取り専用のフィールドが作れるという話をしました。 この時点ではまだクラスや構造体、値型と参照型の違いなどについて触れていなかったのでreadonly修飾子の簡単な紹介だけに留めましたが、 項で改めてreadonlyについて説明します。 整数などの基的な型に対して使う分には特に問題は起きないんですが、構造体やクラスなど、複合型に対して使うときには注意が必要です。 参照型のフィールドに対して readonly readonlyに関して最も注意が必要な点は、readonlyは再帰的には働かないという点です。 readonlyを付けたその場所だけが読み取り専用になり、参照先などについては書き換えが可能です。 例えば以下のコードを見てください。Programクラスのフィールドcにはreadonlyが付いていますが、 cが普通に書き換え可能なクラスのフィールドなので、クラスの

    readonly の注意点
    s_ryuuki
    s_ryuuki 2019/04/21
  • [雑記] 動的コード生成のパフォーマンス(C# によるプログラミング入門)

    概要 .NET Framework のバージョンが上がるたびに色々と追加され、 今や、動的コード生成にもさまざまなやり方が。 ということで、並べて比較してみたいと思います。 「動的 = リフレクション = むちゃくちゃ遅い」というイメージをもたれる方も多いと思いますが、 実際のところ、1度生成したコードをキャッシュしておくなどの工夫をすれば、意外と許容範囲なパフォーマンスが得られます。 (GUI の描画部分やネットワーク通信部分の遅延と比べれば、演算部分の数倍程度の差は取るに足らない場合が多く、 過剰に気にする必要はありません(もちろん、状況次第)。) 比較コード含めたソースコード一式: DynamicPerformance.zip ポイント 毎回リフレクションを呼び出すのはやっぱりかなり(2~3桁)遅い。 キャッシュ機構を使えば、静的なコードの数倍程度までは速くできる。 C# 4.0 の

    [雑記] 動的コード生成のパフォーマンス(C# によるプログラミング入門)
  • [雑記] デリゲートの内部

    概要 デリゲートは、内部実装的には「インスタンスと関数ポインターをペアで管理しているクラス」になっています。 ここではデリゲートの内部挙動と、 それを踏まえたパフォーマンス上の注意点を説明します。 デリゲートは .NET ランタイム内で特殊な扱いをされていて、 デリゲート内部で起こっていることをそのまま C# で書くことはできないので、 ここでの説明は疑似コード的なものになります。 型定義 例えば、以下のようなデリゲートがあったとします。 delegate int F(int x); これは内部的には以下のような扱いになっています。 概ね、インスタンスと関数ポインターのペアです。 class F : System.Delegate { object Target; IntPtr FunctionPointer; // 実際には Delegate クラスのメンバー // あと、object

    [雑記] デリゲートの内部
    s_ryuuki
    s_ryuuki 2018/02/25
  • 小ネタ インデックス付き foreach

    foreach ステートメントで、インデックス付きで列挙したいことが時々あります。 今回は、そういうときの対処方法について。 というか、C# 7が待ち遠しくなる話。 配列やList<T>であれば以下のようにも書けます。 for (int i = 0; i < length; i++) { var item = array[i]; Console.WriteLine($"index: {i}, value: {item}"); } IEnumerable<T>の場合にはこうは書けず、 現状だと、以下のようにループの外側に1個変数を作る必要があったりします。 var i = 0; foreach (var item in items) { Console.WriteLine($"index: {i}, value: {item}"); i++; } ループの外側に変数iが漏れるのが嫌なのと、

    小ネタ インデックス付き foreach
    s_ryuuki
    s_ryuuki 2018/01/06
  • ビルドで使う C# コンパイラーを差し替える

    Visual Studio 2017 15.5で、C# コンパイラーのコード生成の仕方がちょっと変わりました。 その余波で起きる問題を回避するために、Visual Studio は 15.5 のまま、C# コンパイラーのバージョンだけを下げる方法について話します。 背景 C# コンパイラーが出力するコードのどこが変わったか 15.5 の世代では、とにかくいろいろパフォーマンス改善を行っています。 .NET Coreのランタイムや標準ライブラリのパフォーマンスも1~2割上がっています。 Visual Studioも、ソリューションのロードにかかる時間が半減していたりします。 C# コンパイラーも、コンパイラーが出力するコードがより速くなるように微妙に調整が入っています。 コンパイラーの出力結果なんですが、今まで int (符号付き)だったところが uint (符号なし)で生成されていたりしま

    ビルドで使う C# コンパイラーを差し替える
  • C# でビットフィールド

    csharplangに、 C++のビットフィールドみたいなの、C# にもほしい (任意のビット数を表す)bit 型が欲しい みたいなのが投稿されていまして。 「それ、ライブラリとアナライザー、ちょっとしたソースコード生成でできるよ。」という話。 BitFields ライブラリ ということで実装してみたのがこちら。 BitFields ライブラリのソースコード 利用例(double/floatの内部ビット操作とか、RGB555形式とか) 他に、昔実際に仕事で書いたビットフィールドの例 昔、ビットフィールド的なものを手作業実装してた時に、「これはコード生成でやりたい…」とか思ってて、 できる宛まではついてたんですが。 なんだかんだ言ってアナライザーを書くのは結構めんどくさいんで、放置してすでに数年。 まあ、いい機会だから久々に重い腰を上げてアナライザー書いてみるかと思って作ったのが上記のBit

    C# でビットフィールド
    s_ryuuki
    s_ryuuki 2017/05/06
  • C# 7 の新機能

    C# 6からはC#コンパイラーがオープンソース化されたわけですが、 C# 6の言語仕様自体はオープン化前から大筋が決まっていました。 C# 7は、仕様を決めるかなり早い段階からすべてがオープンとなる初めてのバージョンになります。 C# 7以降のC#の大きなテーマとしては以下のようなものがあります。 データ中心の設計 パフォーマンスや信頼性の向上 C# 7にはその最初の一歩となる機能がいろいろと追加されています。 また、この大きなテーマ以外にも、こまごまとして改善が何点かあります。 データ中心の設計 伝統的なオブジェクト指向的な発想は多くの場面で有用ですが、別の発想を持つ方が好ましい場面もあります。 オブジェクト指向では、具体的なデータは隠蔽し、メソッド越しにデータを操作します。 振る舞い中心(behavior-centric)な設計になります。 一方で、関数型言語では、純粋なデータ(C#で

    C# 7 の新機能
    s_ryuuki
    s_ryuuki 2016/11/17
  • Unity 5.5でasync/await使えた話

    Unity 5.5 ベータを入れてみたという話。 ブログ曰く、「Mono C# コンパイラー がMono4.4にアップグレードしました。」とのことなので、これ、C# 6使えるはずよね?と。 公式サポートはC# 4 リリースノートを見ると、「C# 4です」って書かれてるわけですが。 Mono 4.4のコンパイラーを使っててC# 6使えないとかお前は何を言っているんだ… まあ、標準ライブラリの方が .NET Framework 3.5相当のままなので、Taskクラスが使えない。 なので当然、普通にやるとasync/awaitが使えない。 その状況下で「C# 6対応」とか言っちゃったら、問い合わせ押し寄せてやばいでしょうから、公式には「C# 4」と言わざるを得ないのはわかります。 要するに、コンパイラー的にC# 6に対応している状況で、langversionオプションを指定してわざと4に絞ってる

    Unity 5.5でasync/await使えた話
  • Unity上でasync/await: 背景

    まずasync/awaitについて、 (Unityでない)通常のC#開発の場合がどうとか、 Unityで何が問題で使えなかったかとか、 Rxとの住み分けとかについて書こうかと思います。 C# 5.0: async/await の登場 C#界隈で非同期処理がらみの話題がホットになったのはだいたい2010年前後からです。 当時は、 F# にコンピューテーション式による async ワークフローが登場 家のRxが登場 これらから少し遅れて、C# 5.0 (async/await)のプレビュー版が登場 という感じです。 最近になって、Rxを参考にした非同期処理ライブラリが、 JavaJavaScriptなどで実装されていて注目されていますが、 その一方で、C#ではC# 5.0のasync/awaitが主流になりました。 理由はおおむね、 async/await はプログラミング言語側のサポー

    Unity上でasync/await: 背景
  • C# によるプログラミング入門 / ++C++;// 未確認飛行 C

    C# によるプログラミング入門です。C# 初心者の方はもちろん、これからプログラミングを始めようという方も対象としています。

    C# によるプログラミング入門 / ++C++;// 未確認飛行 C
  • 1