ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

C#コミュの読み取り専用ローカル変数

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めまして。

まずは簡単に自己紹介
プログラミング歴は10年くらいです。
言語を覚えた順番は C言語 -> C++ -> Java -> C# ですね。

そして本題
C#の文法で分からない事があります。
読み取り専用の参照型ローカル変数を作る方法はあるのでしょうか?

他の言語で例を示しますと
・C++では my_class* const myc = new my_class();
・Javaでは final MyClass myc = new MyClass();
と書きますがC#ではどう書くのかが分かりません。
ひょっとして方法がないですか !?

読み取り専用にしたい目的は
(1)プログラムの読み手に、スコープを抜けるまで変更しない意志を伝える。
(2)コンパイラーに変数の不変を保証させる。
(3).NETランタイムの最適化を控えめに期待する。
(4)僕の好み。(^^;)

調べた内容
・const ローカル変数には使えるのですが、参照型はstringとnullしか指定出来ません。
・readonly ローカル変数には使えません。
他に相当する予約語が見あたりませんでした。

あくまでコード品質を上げるための手段として使いたいので
裏技を知りたいわけではありません。

ご存じの方がいらっしゃいましたら教えていただけると幸いです。

コメント(7)

私も詳しくは解りませんが、無いのではないかと思います。
その理由として

>(1)プログラムの読み手に、スコープを抜けるまで変更しない意志を伝える。

プログラムの「読み手」を誰かと考えた場合、本人もしくはクラスを提供するのであれば第三者。
第三者であればカプセル化という考えから言うと、ReadOnlyのプロパティで提供するのがセオリーなので、外部に公開されていることに関してはこれで解決できます。
今回の問題はそれに該当しないケースであると考えますが、自作クラスは「自分のテリトリー内」であると考えると不用ではないかというのが私の考えです。
「スコープを抜けるまで変更しない意志」に関しても.NETでは「そもそも変数名が解らなくなるほどステップの多いコードは書かない」「もしステップ数が多いのであればつくりを見直す」というのが基礎概念だと私は考えています。
その為、コード品質を上げるのであれば「意思を示す必要が無い程度にコンパクトにまとめる」が.NET流ではないかと思います。

※あくまで私なりの解釈なので意見の相違があるのは十分承知の上です


>(2)コンパイラーに変数の不変を保証させる。
>(3).NETランタイムの最適化を控えめに期待する。

.NETの場合は(デフォルトでは)メモリ領域は連続しないため無意味ではないでしょうか?
melfina さんの質問ですが、C#言語仕様を見たところ「方法はない」ようです。

仕様書によると、ローカル変数宣言にreadonly等の修飾子は付加できないようです。
「ではconstは?」と言われそうですが、それはローカル変数宣言ではなくローカル定数宣言となります。


ところで・・・。

あろTAKE! さんは、例えばソース コードのレビューなどには参加したことがないんだろうか?
レビュー参加者も「プログラムの読み手」になりますし、読み手なんていっぱいいると思います。
確かにコードレビューでは全員が読み手になりますね。すっかり抜けてました(^^;
コードに触れる人全員(この場合、実際にコードを触る人という意味ではなく広義で)が読み手になると思います。本人という言い方が不味かったですね。訂正しますm(_ _)m

「変数の不変の保証」は即ちコーディングミス防止にも繋がりますのでより安全なコードになる有効な手法だと思います。(4)の理由には恐らくそのような意図があるのだと思います。

そこで「だったらそのような便利な機能を実現するにはどうすればよいか?」となるのが普通です。しかし、そうではなく「そのような機能が必要になるほど長いコードを組むべきではない」というのが.NET流なのではないかと考えるわけです。
つまり「どちらが視認性が高いか」という視点になると思います。
もちろん「そのような便利な機能があるに越したことは無い」のは事実なのですが・・・(^^;
やはり言語仕様にはありませんか...

「そのような機能が必要になるほど長いコードを組むべきではない」
現実に1000行位のメソッドを書く人がいるんですよね...
変数の使われ方を追うのが大変なので欲しい機能でした。
1000行ですか・・・。
なんとかリファクタリングできないものでしょうか?
.NETの場合、コードを減らす工夫が随所にあるため感覚的に言えばC++の半分程度のコード量で同じ機能をより安全に作成できると考えています。
(※注:あくまで感覚的な話ですが)
C#はある意味特殊なので、リファクタリングを繰り返すことによりコード品質を上げていくという手法が一番似合っていると思います。
ただ、現実的には「動いているコードは触るな」等という「自分のコードに自信の持てない人の意見」が環境的にリファクタリングを難しくしているというのはありますが。
始めまして。
私も melfina さんとほぼ同じ経歴です。一番初めに覚えた言語は N88Basic でしたが(^^;

参照型の const が string と null しか使えない点ですが、C++ からの経緯を考えると採用されなかった理由が分かるのではないかと思います。

C++ では、クラス内の値の変更を防ぐために以下のように宣言できます。

 const Hoge value = new Hoge();

または

 Hoge const value = new Hoge();

となります。更にポインタでも同様に、

 const Hoge *pValue = new Hoge();

と記述できます。この場合、Hoge クラス内の状態は変更できません。
一方、変数の代入だけを防ぐためには以下のように宣言します。

 Hoge *const pValue = new Hoge();

スタックへの割り当て時には const の位置を入れ替えてもクラス内の値の変更を防ぐことになってしまうことに気付かれたと思います。ややこしい話ですが、変数の代入だけを防ぐにはポインタにする必要があります。これを鑑みて C# の言語使用を見てみると、ポインタを意識しなくても済む C# で const 宣言をすると、C++ で言うスタックへの割り当て時と同じ宣言になってしまいます。C++ から発展した言語構造を考えると、const 宣言をして変数の代入だけを防ぐ方法は非常に分かりづらくなります。
私もこの手の変数の代入を防ぐ定数宣言は欲しいと思いますが、なかなかしっくりくる構文がありませんね^^;

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

C# 更新情報

C#のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング