Xamarinのサポート終了

弊社でも使用しているMicrosoft Xamarinのサポートが間もなく終了します。
iOS関連と合わせて開発環境の状況を整理しました。

Microsoft関連
- 2024/5/1:Xamarin.Android サポート終了
- 2024/5/1:Xamarin.Forms サポート終了
- 2024/5/1:Xamarin.iOS サポート終了
- 2024/8/31:Visual Studio for Mac廃止

iOS関連
- 2024/4/29:ストアへのアプリは、Xcode 15 と iOS 17 SDKが必要

既存のiOSアプリは、ストアがXcode 15が受け入れられるまではアップデートは可能と思われます。
Visual Studio for Mac廃止に伴い、
MacでのC#開発用IDEの代替としてはVisual Studio Code、
または仮想Windows上のVisual Studioが位置づけされているようです。
MacでUnity開発などを行っている場合は大きな影響がありそうです。

弊社でも今後はモバイルアプリは.NET MAUIに移行していきます。

Visual Studioの便利機能

C#の開発はVisual Studio 2022で行っています。
VSは機能追加のアップデートも頻繁に行われており、便利な機能も多くあります。
ここでは「クイック ウォッチ」と「IEnumerable Visualizer」を紹介します。

実行中にブレイクポイントで停止させて、
オブジェクトの状態を確認するシーンは数多くあると思います。
どのようなIDEでも変数やオブジェクトをウォッチする機能はありますが、
VSでは変数やオブジェクトを右クリックして「クイック ウォッチ」があります。
通常のウォッチと同じような専用の画面が表示され、特に多くの情報を一覧で見たい場合に有効です。

「IEnumerable Visualizer」はIEnumerableな変数にカーソルを合わせると表示される、
「表示」から選択できます。
匿名クラスで欲しい情報を集めてIEnumerableな変数にしておけば、
その情報をCSVかExcel形式で出力することもできるので、
デバッグやデータをExcelで検証する場合などに重宝しています。

関連を表す矢印には気を付ける

我々は物事の概要を伝える場合に、よく概念図を利用します。
例えばシステム全体図、サーバーとクライアントの関係、クラスAとクラスBの関連などです。
この時関連を表すのに矢印をよく使いますが、図を描くときにも読むときにもとても注意が必要です。

例えばクラス図においては、
A→B はAがBを知っている場合に使いますが、その逆はありません。
同じようにして、
例えばモデルと画面の分離アーキテクチャMVVMを表現すると、V→VM→M となります。
上の2つの例は参照と言い換えることができます。

MVVMを説明する図で V⇆VM⇆M と表現されている場合もあります。
この場合は単にVとMが直接繋がっていないことを強調している場合もあれば、
単純なデータの流れを表しているとも考えられるし、
イベントまで考えると、VはVMを知っているし、VMはイベント発行側なのでVへの参照を持つので、
これもやはり参照を表した矢印と考えることもできます。

大切なのは何を表現しようとした矢印なのかをしっかり考え、
1つの図の中で、参照とデータのような意味の異なる矢印を使わないようにすることです。

画面のデザインは難しい

2024年 本年もどうぞよろしくお願い申し上げます。

先日Windowsのソフトで画面の実装を行う機会があり、
それほど複雑な画面ではないものの、ユーザーにとって視認性の高い画面にする必要がありました。

仕様書の段階で画面のイメージは概ね出来上がっていたものの、
実装段階になるとデザインがなかなか上手くできずに困り、
結局、この件ではデザイナの方にデザインをお願いすることになりました。

WPFやMVVMなどのフレームワークが整っている環境でも、
実際にはデザイナではない開発者が、画面のデザインや実装も担当する場合が多いと思います。
その場合でもデザイナの方が行った目標とするデザイン(ゴール)がきちんとあれば、
実装はとてもやりやすいと感じました。

マイコン開発でのリンカ設定

C言語でマイコン開発を行っている中で、関数外で宣言した変数の値が書き換えられない現象に遭遇しました。

static bool _initializedA;           // A
static bool _initializedB = false;   // B

void init() {
  _initializedA = true;
  _initializedB = true;
}

上のようなコードで、Aは関数内で書き換え可能ですが、Bは書き換えされず、関数を抜けても _initializedB の値が false のままという内容でした。コンパイルおよび実行時にも警告やエラーが発生せず、最初理由がよく分かりませんでした。

原因はリンカの設定によるものでした。Bのほうは初期値ありなので.dataセクション(ROM)に配置され、リンカのデフォルトの設定ではROMからRAMへのマップが行われていませんでした。

実はこのときは普段使用しているものとは異なるマイコンでの開発であったため、開発環境も普段とは異なり、デフォルトのリンカの設定がこのようになっているとは知りませんでした。

C言語での開発はオープン系言語と比べると、このような点でも難しく感じます。せめて警告やエラーが発生すればもっと早く気が付けるのですが、言語知識だけでなく、経験や経験に基づく感も必要なようです。

初めてのCとC++

これまでの業務ではC#を使ってきました。
今回初めてCとC++に携わる機会があり、学習しました。
せっかくなのでModern C, C++ と言われる比較的新しいバージョンです。

C#を使い慣れているとCやC++ではロジックのコード量が増え、
こんなこともできないのか、と思う一方、
特にメモリの扱われ方などはより理解が深まりました。

ただC++は言語仕様としてもかなり複雑で、Cの次に学ぶにはとても難しい印象です。
なのでC++習得するには先にC#等を理解して、オブジェクト指向の特徴や、
最近の言語の機能、プログラミングスタイルなどを知った後のほうが、
C++を使ってどのような設計や関数を目指すべきかということがよく分かると思います。

RustもC++とよく比較されて人気があるようなので、
今後触れてみたいと思います。

初級ソフトウェア品質技術者 資格試験

11月に、初級ソフトウェア品質技術者 資格試験を受けました。
ソフトウェアの品質技術を身につけ、品質の向上を目的とした試験で、
ソフトウェアの品質向上に関する知識を体系的に学ぶ為に受験しました。

試験に関しては、初級試験の合格率は40%前後なので、きちんと学習しないと合格は難しいようです。
また今回の試験から新しいシラバス(Ver.3.0)となっており、出題範囲も広くなっています。
私の場合はシラバスの用語をピックアップしながら、テキストを読み進めるスタイルで学習しました。
実務で品質を扱っていないと用語や概念が難しい部分もありますが、
ソフトウェアのライフサイクル(企画~廃棄まで)を意識して、
今はどのプロセスの内容の事を指しているのかを把握する事が重要だと感じました。

学習した内容を生かして、
今後は社内のプロセス改善や品質向上に役立てていきたいと思います。

ASP.NET Core MVC

仕事で ASP.NET Core MVC を使用しました。
社内では既に実用していたのですが、
プロジェクトの作成や新規で導入を行ったのは、個人的に初めてとなります。

Razor構文やHTML、JavaScriptでwebページや処理を記述する事になるので、
慣れないと少しぎこちない部分もありますが、新鮮でした。
比較的新しいフレームワークなので、
例えばxxxControllerのxxxが、Viewsのxxxフォルダと対応したり、
1つのViewに相当するyyy.cshtmlがyyy()メソッドと対応したりなど、
フレームワーク側のサポートがあって使いやすいと感じました。

このようなサポートはその命名ルールを強制する事になるので、
開発者としては迷いが少なく助かります。
これをきっかけに、Web関連の知識や技術も学んでいければと思います。

C# オブジェクト初期化子でプロパティのプロパティを初期化

C#でオブジェクト初期化子という構文があります。
オブジェクトの作成時にアクセス可能なプロパティやフィールドに値を割り当てるもので、
例えば次のように書きます。

var person = new Person() {
    Name = "Taro",
    Id = 1,
};

これは以下と同等です。

var person = new Person();
person.Name = "Taro";
person.Id = 1;

メリットは初期化の内容が1箇所に集まることで、
初期化中に間違って別の処理が混入することが無いことです。
なので積極的に利用すべきですね。

初期化できるのはアクセス可能なメンバーに限定されるので、
例えば以下のケースはコンパイルエラーとなります。

var parent = new Parent() {
    Person = new Person(),  //Person プロパティはsetできないのでコンパイルエラー
};
class Parent {
    public Person Person { get; } = new Person();
}

class Person {
    public string Name { get; set; }  //プロパティ
    public int Id;  //フィールド
    public List<int> RelatedId { get; }

    //コンストラクタ
    public Person() {
       RelatedId = new List<int>() { 1 }; //要素"1"で初期化
    }
}

Parentオブジェクト初期化子内で、
Personプロパティのプロパティを設定したい場合は以下のように書きます。

var parent = new Parent() {
    Person = { Name = "Taro", Id = 1 }
};

ではList<int>に値を指定した場合はどうなるでしょうか?

var parent = new Parent() {
    Person = { Name = "Taro", Id = 1, RelatedId = {10, 20}}
};

RelatedIdはコンストラクタで初期化された値に値が追加され、
この場合、要素が{1, 10, 20}の要素数3のコレクションとなるようです。
あまり使いどころは無いかもしれませんが、覚えておくとどこかで役に立つかもしれません。

ソフトウェアの完成

製作しているソフトウェアが完成すると嬉しいものです。
でも完成のタイミングとはいつなのでしょうか?
実装が全て完了して、
仕様を満たしているか、動作は問題無いか等の確認を行い、
全て合格した場合に完成となります。

ただ動作テストの時にいろいろ気付くこともあり、
そのときに「この部分は使い勝手が悪い」「もっとこうしたほうが良い」など、
特にUI(ユーザーインターフェース)周りで改善案が浮上します。
私の場合はこの時点で挙がった改善案をtodoとして、
それらを解決した時点で完成としています。

デザインやUIの部分は、想定する使い方が変わると、
「使いやすさ」を実現する方法も変わってしまいます。
これらの全て実装すると開発期間やコストをオーバーしてしまいますので、
まずは普通の使い方で不便を感じない実装が重要だと考えています。

それでも「期待以上だった」とお客様に言って頂けるような、
そんなソフトウェアを目指しています。