トップ «前の日記(2005-09-08) 最新 次の日記(2005-09-10)» 編集

日々の破片

著作一覧

2005-09-09

_ 代替ストリーム

伊原さんのメモ(追記:イの字を間違えてました。ごめんなさい)。

これいろいろ使い道があるはずなのだが、FDへコピーした瞬間に消失しちゃうという問題があったけど、今はFD使わないしな(でもFTPしたらやはり消えるだろう)。

#ゾーン情報の保存に使うというのは思わず納得。

・メタデータ

・構造化記憶

_ VB.NETの怖い話

今日聞いた話。
// I like C#
public class Foo {
    protected int facility;
    public int Facility {
        get { return facility; }
    }
    ...
}

継承したクラスはフィールドを直接アクセスすることで設定可能。それ以外の利用者にはread onlyとして提供。

これは、VS2005 RCではVB.NETで継承するとエラーになる。

元々CTSには違反している(はず)これはCLS準拠違反(確認しました。多謝)。VB.NETはケースインセンシティブだ。したがって、これは矛盾しているので×。

VS2005 ベータまでは、VBからはプロパティしか見えていなかったのに。

では、どうするのが正解か?

(1) protected int m_facility;
(2) protected int _facility;
(3) protected int facility_;

どれも標準コーディング規約に違反している。

(4):
protected int facility;
public int getFacility() {
    return facility;
}

うむ。八方丸く収まった。

か?

追記:

しょせん、他人事とあまり深くは考えていなかったけど、結構、やっかいであるなぁ。コメントにはああ書いたけど、プロパティのセッタとゲッタでアクセス指定子を変えるなんて細かいことはできるんだっけ? というのが1つと(.NET 2.0でできるようになったから−とLady.BUGさんのコメントではなっている−コンパイルエラーにするようにしたのかも)、それはそれとしてprotectedフィールドを利用したいという場合もあり得る点。

#継承関係があるクラスは、もう、どうしようもなく密結合しているんだから、それを前提として設計して良いと思っている。

たとえばpublicなセッタではレンジチェックするが、直接フィールドをさわることで、特権的な設定をサブクラスには許可するというような場合。

もちろん、
protected void setFacilityWithoutCheck(int x);
とか
protected void setFacilityCheatly(int x);
とか

あくまでも変なメソッドを用意しても良いかも知れないけど、外部インターフェイスで機能仕様そのものなpublicなメソッドと違って、あくまでも内部処理の延長なprotectedなアクセスであれば、そこまでムキになって変なバイパス用メソッドを用意する必要もなかろう。

つまり、問題は、フィールドに対して透過的なプロパティのあるべき名前は何か? ということ(あるいはその逆)。

Javaだと何も考えずに

int facility; 
public void setFacility(int newFacility) {
    facility = newFacility;
}
public int getFacility() {
    return facility;
}

と書けるけど、C#/VB.Netではその手は利用できない/あまり利用しない方が良いのではないかということ。だからといってm_facilityとか_facilityとかfacility_とか nFacilityってのはいやなこった。

スロットとか?

public class Foo {
    protected static readonly FACILITY = 0;
    protected int[] attributes;
    ...
    public int Facility {
        get { return attributes[FACILITY]; }
    }
    ...
}

#これもダメじゃん……。enumにして名前空間を区切れば良いのか? Javaと違って数値だったはずだし。

本日のツッコミ(全8件) [ツッコミを入れる]
_ Kazz (2005-09-09 12:22)

>継承したクラスはフィールドを直接アクセスすることで設定可能<br><br>C#とVBの互換性を気にするのであればサンプルのfacility等インスタンスフィールドをprotected(もちろんpublicも)スコープで定義するのは禁止にする、というのでは駄目でしょうか。

_ Kazz (2005-09-09 12:30)

自分で書いておいてなんですが<br>>C#とVBの互換性を気にするのであれば<br>protectedスコープのインスタンス変数へのアクセスを禁じるのと言語間互換性とはあまり関係無いですね。偶々今回の問題に対して書いたことで結びつけましたがこじつけでした。

_ Lady.BUG (2005-09-09 14:28)

NET 2.0 でどうするか?<br><br>であれば、field は private にして、protected set {} と public get {} でいいんじゃないでしょうか。

_ arton (2005-09-09 14:47)

セッタ=protected<br>そうですよね。

_ Lady.BUG (2005-09-09 16:12)

> あくまでも内部処理の延長なprotectedなアクセス<br><br>という要件に対して .NET では FamilyAndAssembly アクセスレベルを利用するのが良いかもしれません。これならコンシューマーである VB からは見えないので CLSCompilant を維持できます。<br>ただし C# ではこのアクセスレベルをサポートしていません。(C++ なら private protected int facility で宣言可能)<br><br>あ、<br>> 元々CTSには違反している(はず)。<br>は、CLS ですよね、CTS では「同じ名前で違う型のフィールド」すら許していますので、C# ではかけませんが int a; と object a; が同居できます。

_ Lady.BUG (2005-09-09 16:13)

↑ 前半、VB のコードが C# でかかれたクラスのコンシューマーとしてアクセスする必要があるフィールドであれば、「あくまでも内部処理の延長なprotectedなアクセス」を逸脱してしまっている、という前提で。

_ Kazz (2005-09-09 18:30)

Lady.BUGさんの方法以外で、あくまでFacilityというプロパティ名とprotectedで直接のフィールドアクセスにこだわるのでしたら素直にフィールドの名前を変えてしまうほうがすっきりすると思うんですけど。<br><br>protected int facilityValue;<br><br>とか。<br>>m_facilityとか_facilityとかfacility_とか nFacilityってのはいやなこった。<br>ということなのですから好みからすると駄目そうですね。私もアンダースコアをつけるのは嫌いなんで人のことは言えないですけど。

_ arton (2005-09-09 21:04)

意外とValueを後置するというのは好きかも知れません(違和感を覚えない)。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|

ジェズイットを見習え