「C#が書ければ大丈夫」の幻想:僕が海外の現場でぶち当たった、技術力以外の「壁」
やあ、どうも。海外の片隅で、今日も今日とてC#のコードと格闘しているITエンジニアです。メインの戦場はWPF。そう、あのWindows Presentation Foundation。今どき「Webだろ」「クラウドだろ」って声が聞こえてきそうだけど、世の中にはね、金融とか、医療とか、工場のラインとか、絶対に止まっちゃいけない、しかもリッチなUIが求められるデスクトップアプリの需要っていうのが、ガッツリ存在するわけです。僕はそういう、ミッションクリティカルなシステムの設計と開発を、ここ(海外)でやっています。
さて、このブログを読んでるってことは、あなたも「いつかは海外でエンジニアとして働いてみたい」とか、「もうすぐ海外に行くけど、ぶっちゃけどうなの?」って思ってるクチかな。
僕もね、日本にいた頃はそうだった。「C#なら誰にも負けない」「WPFのMVVMパターンなら完璧だ」「非同期処理(async/await)もバッチリ使いこなせる」。そういう技術的な「貯金」が、海外で働く上での最強の武器になるって、本気で信じてた。パスポートと、GitHubアカウントと、C#の知識さえあれば、世界中どこでも戦える。そう思って意気揚々と飛行機に乗ったわけです。
結論から言うとね、その考え、半分正解で、半分は「甘すぎた」。
海外の現場に放り込まれて、まず気づくこと。もちろん、技術力は「入場券」として絶対に必要。これがないと話にならない。僕のC#やWPFのスキルが、最初の信頼を勝ち取るのに役立ったのは事実。
「ああ、こいつはちゃんとSOLIDの原則を理解して設計できるな」とか、「パフォーマンスを意識したXAMLが書けるな」とか。そういう技術的な「言語」は、世界共通。これは間違いない。
でも、本当の勝負はそこからだったんだ。
僕が最初にぶち当たった「壁」。それは、技術力じゃなくて、「技術力で解決できない問題」の壁だった。
例えば、ある日のミーティング。プロジェクトマネージャー(PM)が、次のスプリントで実装する機能について説明してる。僕は技術的な仕様を必死にメモしてる。でも、なんか空気がおかしい。隣に座ってるシニアエンジニア(彼は生粋の地元民)が、PMの話を遮って、こんなことを言い出した。
「待ってくれ。その機能、そもそも『なぜ』必要なんだ? ユーザーのAさんは、先週のデモで『このボタンはむしろ邪魔だ』って言ってなかったか? C部署が要求してるデータは、B部署のシステムと連携すれば、こんな新しい画面を作らなくても取れるはずだ。君(PM)は、AさんとB部署とC部署、全員と話した上で、この『設計』を持ってきたのか?」
…僕は、凍りついたね。
僕は「どうやって(How)作るか」ばっかり考えてた。WPFでどういうリッチなUIを実現しようか、どのデザインパターンが最適か、非同期でどうやってデータをスマートに引っ張ってくるか。
でも、彼は「なぜ(Why)作るのか」「そもそも(What)作るべきなのか」を、PM以上に深く掘り下げてた。
彼が見ていたのは、僕のWPFアプリの画面じゃない。ユーザー(Aさん)の不満、B部署の持つデータ、C部署の真の要求、そしてPMの調整不足。それらすべてが複雑に絡み合った「システム全体」だったんだ。
その時、ハッとした。
「ヤバい。俺、このままだと、ただの『C#が書ける作業員』で終わる」と。
日本にいた頃は、仕様書は(だいたい)完璧だった。設計も(だいたい)固まってた。僕らはそれを「いかに高品質に、いかに速く」作るかを競ってた。でも、海外(特に僕のいる環境)の現場は、もっとカオスだった。仕様書は「たたき台」以下。問題は「 unstructured(非構造化)」で、誰も正解を持ってない。
GitHub CopilotやChatGPTみたいなAIが、僕の書くC#のボイラープレートコードを猛烈な勢いで駆逐してるのを、君も知ってるよね? 正直、単純な「How(どう作るか)」の部分は、もうAIに勝てないかもしれない。
じゃあ、僕らの価値はどこにある?
そう、それは「AIがまだ解けない、複雑で、非構造化で、人間臭い問題を解く力」だ。
それは、教科書には載ってない。
それは、C#のシンタックスを覚えることでも、WPFの新しいライブラリを追うことでもない。
僕は、それを「Cognitive Agility(思考の俊敏性)」と呼んでる。
技術は陳腐化する。僕が愛用してるWPFだって、いつまで続くかわからない(まあ、.NET Coreで蘇ったから、まだまだ戦うつもりだけど!)。10年後、僕らは量子コンピューティングのコードを書いてるかもしれない。
大事なのは、特定の「技術」にしがみつくことじゃなくて、新しい技術が出てきたときに「素早く適応し(Lifelong learning)」、目の前のカオスな問題に対して「本質を見抜く批判的な目(Critical thinking)」を持ち、そして、自分の作る小さなコンポーネントが、会社全体、いや社会全体という「巨大なシステム(Systems thinking)」の中でどういう役割を果たすのかを想像できる力。
このブログでは、僕が海外のC# / WPFエンジニアとして、日々どうやってその「思考の俊敏性」を鍛えているか、その具体的な「人生術」を、実体験ベースでシェアしていきたいと思う。
技術オタクな話もするけど、それ以上に、「どうやって考えるか」っていう、AI時代にエンジニアとして「指名され続ける」ための、超・実践的なヒントを詰め込んでいくよ。
AIの「コピペ」と人間の「思考」:コードが書けるAI時代に、C#エンジニアが真に価値を生む場所
「起」で話した「AIに仕事奪われるかも」っていう漠然とした不安。海外の現場に来て、GitHub CopilotみたいなAIコーディングツールと「共同作業」するようになって、その答えがハッキリと見えてきた。
結論から言うとね、AIは「超優秀な、だけど指示待ちの新人」だ。
あるいは「膨大な知識を持ってるけど、空気が読めないインターン生」かな。
僕の戦場であるC#とWPFの開発現場。例えば、WPF特有の「お作法」、あるじゃない?
ViewModelを作るとき、INotifyPropertyChangedを実装して、おびただしい数のプロパティ定義(setの中でRaisePropertyChanged()を呼ぶアレ)を書かなきゃいけない。正直、面倒くさい。
XAMLで、ちょっと凝ったDataTemplateやControlTemplateを書こうとすると、シンタックスがまあまあ複雑だ。
こういう「How(どう書くか)」、つまり「定型的だけど面倒な作業」において、AIは神だ。
「こういうプロパティ持ったViewModel作って」とコメントで指示すれば、AIは爆速でC#のコードを吐き出す。INotifyPropertyChangedの実装も完璧だ。僕が手でタイプするより10倍速い。
「このデータをリスト表示するListViewのXAML書いて」って言えば、ItemsSourceへのバインディングが設定されたXAMLがドンと出てくる。
マジで助かる。おかげで、僕は「どう書くか」に悩む時間を大幅に節約できるようになった。
でもね、ここが超重要なんだけど、AIは「なぜ(Why)それを作るのか」「本当に(What)それが必要か」については、一切答えてくれない。
AIが吐き出した完璧なViewModel。でも、そのプロパティ、本当に全部必要だった?
AIが作ったキレイなListView。でも、その画面、そもそもユーザーは「リスト表示」じゃなくて「グラフ表示」を求めてたんじゃないの?
AIは、僕が「作れ」と指示したものを、最短距離で作るだけ。
僕の指示が間違ってたら? 僕の設計思想がイケてなかったら?
AIは、イケてないコードを、超高速で量産する「凶器」にもなるんだ。
ここで、あの「Cognitive Agility(思考の俊敏性)」の3点セットが、AI時代の僕らエンジニアの「本当の価値」として輝いてくる。
1. Lifelong Learning(生涯学習)の「本当の意味」
海外の現場で「生涯学習」っていうと、みんな「ああ、WPFの次はMAUIね」とか「やっぱりWeb(Reactとか)もやっとくか」みたいな、「次の流行技術」の話だと思いがち。
もちろん、それも大事。僕も.NETの最新動向は毎日追ってる。
でも、僕がここで痛感してる「生涯学習」は、ちょっと違う。
それは**「技術」と「ビジネスドメイン(業務知識)」の両輪を学ぶ**ことだ。
僕が今担当してるWPFアプリは、ある特殊な製造業の「品質管理」に使われてる。
日本にいた頃は、正直「仕様書に書いてあるから」以上の興味はなかった。
でも、海外の同僚たちは違う。彼らはエンジニアなのに、平気で「この部品の『公差(こうさ)』の定義って、ISO規格とASTM規格でどう違うんだっけ?」とか「この検査項目、手動で入力させてるけど、あそこの検査機(ハードウェア)から直接データ(シリアル通信とか)引っ張ってこれないの?」とか、そういう「業務」の話をガンガンしてくる。
最初はチンプンカンプンだったよ。でも、これができないと、AIに指示すら出せないことに気づいた。
AIに「品質管理のVM作って」って言っても、AIには「公差」の意味が分からないから。
だから、僕はC#のコードを書く傍らで、その業界の「業務フロー」や「専門用語」を必死で学んでる。
これが「思考の俊敏性」にどう繋がるか?
業務が分かると、PMが持ってきた無茶な要求(「起」で話したみたいなやつ)の「本当の目的」が見えるようになる。
「ああ、PMはA部署の『作業効率』を上げたいんだな。でも、そのために新しいWPF画面を作るのは(開発コスト的に)最悪手だ。むしろ、今あるB部署のWebシステムと、うちのAPIを連携させるだけで解決するじゃん」
…みたいにね。
WPFという「点」の知識だけじゃなくて、業務という「線」の知識を持つことで、初めて技術的な「代替案」を提示できる。これこそ、AIには絶対にできない「生涯学習」の成果だ。
2. Critical Thinking(批判的思考)は「AIを疑う」力
次に、クリティカルシンキング。これは、AIが吐き出したコードを「鵜呑みにしない力」だ。
よくあるんだ。パフォーマンス改善のタスク。
「このWPF画面、起動がめちゃくちゃ遅いから何とかして」
こういう時、Copilotに「この処理、遅いんだけど」って聞くと、AIは「なるほど! List<T> を HashSet<T> に変えましょう!」とか「ここのLINQをAsParallel()で並列処理しましょう!」とか、小手先の「How」を提案してくる。
でも、僕ら人間の仕事はそこじゃない。
「起」のシニアエンジニアのように考えるんだ。
「待てよ。そもそも、この画面(View)が起動するときに、なんでDBから10万件のデータを(ViewModelで)『全件』読み込もうとしてるんだ? ユーザーが一度に見るデータなんて、せいぜい最初の20件じゃないか?」
これがクリティカルシンキングだ。
AIは「言われたこと(処理を速くする)」はやろうとする。
でも、人間は「言うべきこと(そもそも、その処理、今やる必要ある?)」を指摘する。
僕がやったのは、AIの提案(並列処理)を無視して、設計を根本から見直すことだった。
「UI仮想化(Virtualization)」をWPFで実装し、ViewModelには「本当に表示に必要な分(20件)」だけを非同期(async/await)でロードするロジックに変えた。
結果、起動時間は10秒から0.5秒になった。
AIは「How」を最適化する。人間は「What(何をすべきか)」と「Why(なぜそうすべきか)」を最適化する。
AIのコードを疑い、仕様書を疑い、時には「常識」すら疑う。この「批判的な視点」こそが、僕らの給料の源泉だ。
3. Systems Thinking(システム思考)で「自分のアプリ」の枠を超える
最後、システム思考。
WPFアプリって、PCの中で完結してる「デスクトップアプリ」だから、どうしても視野が「自分のPC」の中に閉じがち。
でも、海外の現場で求められるのは、その真逆だ。
僕のWPFアプリは、巨大なシステムの「ほんの一部」でしかない。
僕のアプリがデータを保存するとき、そのデータはAPI(ASP.NET Coreで動いてる)に投げられ、DB(SQL Server)に格納される。それと同時に、そのデータは、B部署が使ってるWebのダッシュボード(React製)にリアルタイムで反映されなきゃいけないし、C部署が管理してる監査ログ用の別システム(Kafkaとか使ってるかも)にも送らなきゃいけない。
日本にいた頃は「僕の仕事はWPFアプリ。APIから先は知らない」が許されたかもしれない。
でも、ここでは許されない。
「おい、お前のWPFアプリから保存したデータ、Webダッシュボードに反映されないぞ。APIの叩き方、間違ってないか? そもそもB部署とC部署に『仕様変更』の連絡したのか?」
こういうツッコミが、Slackで日常的に飛んでくる。
システム思考っていうのは、自分の書くC#のコードが、会社全体の「システム(=業務フローそのもの)」にどういう影響を与えるかを想像する力だ。
自分のWPFアプリ(点)だけじゃなく、APIやDB(線)、そして他部署のシステムやユーザーの業務(面)まで、全部ひっくるめて「自分の仕事」だと考える。
AIは、僕のWPFアプリのリポジトリしか見てない。
でも、僕は、会社全体のシステムアーキテクチャ図と、なんなら「B部署のあの人、今機嫌悪いから、仕様変更の連絡は丁寧にやろう」っていう「人間関係」まで含めて考える。
これが、AIには絶対に真似できない「システム思考」だ。
「なぜ?」を5回繰り返すだけじゃダメ。WPFの設計図から学ぶ、「システム思考」と「クリティカルシンキング」の鍛え方
「承」で、AIは「How(どう作るか)」のプロだけど、僕ら人間は「Why(なぜ作るか)」と「What(何を作るか)」で価値を出さなきゃいけない、って話をしたよね。
じゃあ、その「Why」を掘り下げる力、つまり「クリティカルシンキング(批判的思考)」や、全体像を把握する「システム思考」って、どうやって鍛えたらいいんだろう?
よくビジネス書なんかには「『なぜ?』を5回繰り返せ」なんて書いてある。
もちろん、それも基本。でも、正直、それだけじゃ足りない。
現場で「なぜ?」「なぜ?」って5回も聞いてたら、「いや、お前が考えろよ」って、海外の同僚(特にシニアエンジニア)に一蹴されるのがオチだ。
僕が海外の現場で気づいた、もっと実践的で、僕らC# / WPFエンジニアだからこそ「しっくりくる」トレーニング方法がある。
それは、「WPFの設計思想そのもの」を、現実世界の問題解決に応用することなんだ。
何を言ってるんだ?って思うかもしれない。
でも、よく考えてみてほしい。僕らが毎日触れているWPFの「MVVMパターン(Model-View-ViewModel)」や「DI(Dependency Injection=依存性の注入)」、「疎結合(Loose Coupling)」といった設計思想は、そもそも「複雑な問題を、どうやって見通しよく整理し、変更に強く(=アジャイルに)保つか」という先人たちの知恵の結晶なんだ。
これ、そのまま「思考の俊”敏”性(Agility)」を鍛えるフレームワークになる。
1. 「MVVMパターン」で、思考と現実を分離する(クリティカルシンキングの鍛え方)
まず、クリティカルシンキングから。
僕らWPFエンジニアは、MVVMパターンが骨の髄まで染み付いてる。
- View(ビュー):見た目。XAMLで書かれた、ユーザーが直接触る部分。
- ViewModel(ビューモデル):Viewの「状態」と「ロジック」を持つ。Viewからは直接見えない。
- Model(モデル):ビジネスロジックの本体。DBやAPIとのやり取り。
そして、この3つは「疎結合」になってる。ViewはViewModelの「どのプロパティをバインディングするか」しか知らないし、ViewModelは「自分がViewに表示されてる」ことすら知らない。
この「関心事の分離(Separation of Concerns)」こそが、クリティカルシンキングの第一歩だ。
海外の現場で、カオスな問題(「起」で話したPMの無茶振りとか)にぶち当たった時、僕の頭の中はこうなってる。
「待てよ。今、目の前で起きている『現象(=View)』と、その背後にある『ロジック(=ViewModel)』、そして『本当の目的(=Model)』をごちゃ混ぜにしてないか?」
例えば、「ユーザーから『このWPFアプリ、ボタンが多すぎて使いにくい』というクレームが来た」という問題。
- ダメな思考(全部ごちゃ混ぜ):「ヤバい、クレームだ。急いでボタンを減らそう。XAMLを開いて、あのボタンとこのボタンを非表示に(Visibility=”Collapsed”)して…」→ これだと、別のユーザーが「あのボタンがないと仕事にならない!」って怒り出すかもしれない。
- MVVM的思考(クリティカルシンキング):
- 【Viewの分析】:「ボタンが多すぎて使いにくい」というのは、あくまでユーザーの「見た目」に対する**『現象』**だ。これは事実として受け止める。
- 【ViewModelの分析】:では、その背後にある**『ロジック』**は何か? そもそも、なぜこんなにボタン(機能)が必要になったんだっけ?→ 設計書を漁る。「A部署は『承認』機能が、B部署は『差し戻し』機能が必要だと言った」。なるほど。
- 【Modelの分析】:じゃあ、彼らの**『本当の目的』**は?→ A部署にヒアリング。「承認ボタンを押したい」んじゃなくて、「自分が承認すべきタスクが『一目で』わかって、それを『一括で』処理したい」が本音だった。→ B部署にヒアリング。「差し戻しボタン」は、実はもう使われてない古い業務フローの「遺物(レガシー)」だったことが判明。
ここまで掘り下げれば、やるべきことは「XAMLでボタンを隠す」ことじゃないって分かるよね。
「A部署専用の『承認待ち一覧』画面(View)を新設し、そこ(ViewModel)に一括承認ロジックを実装する」そして「B部署の差し戻しボタン(ViewModelのロジックごと)は、勇気を持って削除する」が、本当の解決策(What)だ。
「現象(View)」と「ロジック(ViewModel)」と「本質(Model)」を切り分けて考える。
これが、僕らが毎日やってるMVVMの思考法。これを現実の問題に適用するだけで、君の「Why」の深さは劇的に変わるはずだ。
2. 「DI(依存性の注入)」で、システム全体を見る(システム思考の鍛え方)
次に、システム思考。全体像を把握する力だ。
これも、僕らC#エンジニアが(WPFアプリでも、ASP.NET Coreでも)多用する「DI(Dependency Injection)」の考え方が役に立つ。
DIコンテナ(Microsoft.Extensions.DependencyInjectionとか)って、何をしてるか覚えてる?
「このクラス(例: MainViewModel)は、あの機能(例: IUserDataService)に『依存』している」という関係性を、コードの外側(Startup.csとかApp.xaml.cs)で一元管理する仕組みだ。
なぜこんな面倒なことをするかって?
それは、MainViewModelのコードの中に、new UserDataService() みたいに「密結合」なコードを書いちゃうと、後で UserDataService を MockUserDataService(テスト用)や NewUserDataService(新機能)に差し替えるのが、めちゃくちゃ大変になるからだ。
この「依存関係を宣言し、外部から注入する」という考え方。
これが、そのまま「システム思考」のトレーニングになる。
海外の現場で、新しい機能の設計を任された時。
僕は、C#のコードを書く前に、まず「この機能は、何に『依存』しているか?」を徹底的に洗い出す。
「今作ろうとしてる、このWPFの『見積書作成』機能(QuotationViewModel)は…」
IProductService(製品マスタAPI)に依存するな。ICustomerService(顧客マスタDB)にも依存する。IPdfExportService(PDF出力ライブラリ)にも依存する。- あ、忘れてた。
ILoggingService(監査ログシステム)にも依存する。
これをやると、何が起きるか?
自分のWPFアプリ(点)だけ見ていたら絶対に気づかなかった、膨大な「つながり(線)」、つまり「システム全体(面)」が見えてくる。
- 「あれ、IProductService のAPI仕様書、古くないか? データ足りないぞ」→ APIチーム(B部署)に確認だ。
- 「ICustomerService のDB、パフォーマンスやばそう。こんな頻繁にアクセスしたら落ちるかも」→ DBA(C部署)と調整が必要だ。
- 「ILoggingService って、そもそも誰が管理してるんだ?」→ インフラチーム(D部署)とのミーティングが必要だ。
これがシステム思考だ。
自分の作る機能が、システム全体の「どこ」に位置し、「誰」に依存し、そして「誰」に影響を与えるか。
これを設計段階で(DIコンテナの構成を考えるみたいに)見抜けるかどうかが、AIに指示を出す側の「アーキテクト」になれるか、AIに指示される側の「コーダー」で終わるかの分かれ道だ。
まとめよう。
「思考の俊敏性」を鍛えるために、遠くの小難しい哲学書を読む必要はない。
答えは、君が今まさに向き合っている「WPFの設計思想」の中にある。
- クリティカルシンキング:「現象(View)」に惑わされず、「ロジック(ViewModel)」と「本質(Model)」を分離して考えろ。
- システム思考:「依存関係(DI)」を洗い出し、自分のコードがシステム全体(他部署)にどう影響するかを想像しろ。
この2つを、日々のC#コーディングと同じくらい「当たり前」の思考習慣にすること。
これこそが、AIや教科書には絶対に真似できない、君だけの「人生術」であり「得する情報」になるはずだ。
…さあ、この話、もうちょっと「深く」掘り下げてみないか?
量子コンピュータの時代が来ても、あなたが「指名される」エンジニアであり続けるために
さて、ずいぶん長い旅にお付き合いいただき、ありがとう。
海外の片隅でC#とWPFに向き合う僕が、肌で感じてきた「生存術」について語ってきた。
「起」では、僕が海外でぶち当たった「技術力だけでは超えられない壁」の話をしたね。「C#が書ければ大丈夫」という幻想が、いかに脆(もろ)いか。
「承」では、その壁の正体が「AIとの棲み分け」にあると気づいた話をした。AIは「How(どう作るか)」の達人。だからこそ、僕ら人間は「Why(なぜ作るか)」「What(何を作るか)」という領域、つまり「思考の俊敏性(Cognitive Agility)」で価値を出さなければならない。
そして「転」では、その「思考の俊敏性」を鍛える具体的なトレーニング方法として、僕らWPFエンジニアに馴染み深い「MVVM」や「DI」といった設計思想こそが、最強のフレームワークになるという「人生術」を提案した。
最後に、君に伝えたいことがある。
僕がこのブログで最初に「量子コンピューティング」なんていう、突拍子もない単語をフックにしたのを覚えてるかな?
正直、僕も量子コンピュータでC#がどう動くかなんて、まだ全然わからない(笑)。
でも、ポイントはそこじゃないんだ。
大事なのは、**「僕らの想像を超える技術(=量子コンピュータ)が明日スタンダードになっても、生き残れるか?」**という問いだ。
僕らの愛するC#も、WPFも、もしかしたら10年後、20年後は、COBOLみたいに「レガシー」と呼ばれてるかもしれない。それは誰にも分からない。
技術の「How」は、必ず陳腐化する。
でも、「転」で話した「MVVM的思考」や「DI的思考」はどうだろう?
「現象」と「本質」を切り離して考える力。
「依存関係」を整理して、システム全体の影響を想像する力。
これらは、たとえ量子コンピュータの時代が来ようが、AIがどれだけ進化しようが、絶対に陳腐化しない。
なぜなら、それは「技術」ではなく、「人間の思考」そのものだからだ。
カオスで、曖昧で、人間臭い「問題」を解き明かす力。それこそが、僕らエンジニアがAIに「指示を出す側」であり続けるための、唯一無二の価値なんだ。
特に、君が「海外で働きたい」と思っているなら、この「思考の俊敏性」は、技術力以上に君を助ける「最強のパスポート」になる。
海外の現場は、日本にいる時とは比べ物にならないくらい「カオス」だ。
要求は曖昧。仕様書は存在しないか、あっても嘘だらけ(笑)。文化も違えば、価値観も違う。「起」で話したシニアエンジニアみたいに、平気で「そもそも、それいる?」と土台からひっくり返してくる人たちと、毎日渡り合わなきゃいけない。
これって、裏を返せば「思考の俊敏性」を鍛えるには、最高の環境だ。
毎日が「システム思考」と「クリティカルシンキング」の実践(OJT)なんだよ。
だから、恐れないでほしい。
AIの進化を、海外の厳しさを。
それは君から仕事を奪う「脅威」じゃない。君を「ただのC#コーダー」から、「真の問題解決者(プロブレムソルバー)」へと強制的に進化させてくれる「最高の機会」だ。
さて、僕もそろそろ、目の前のWPFアプリの設計に戻るとしよう。
次に君がVisual Studioを開くとき。
ただXAMLのコードを書くんじゃなくて、こう自問してみてほしい。
「このView(画面)が要求されている『本質(Model)』は、本当にこれか?」
「このViewModelのロジックが『依存(DI)』している先は、ちゃんと見えているか?」
その「問い」こそが、君の思考をアジャイルにし、10年後も20年後も、世界中どこへ行っても「君じゃなきゃダメだ」と指名され続けるエンジニアへの、確実な第一歩になるんだから。

コメント