C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 >>
■57429  Re[3]: DataGridViewで透明色のエラーを回避する方法
□投稿者/ 魔界の仮面弁士 -(2011/02/25(Fri) 22:31:42)
    No57427 (赤いガチャピン さん) に返信
    > セレクションバックカラー等を全体的なセルでしか設定できないものだと思っておりました。
    DataGridView のスタイルは、以下の単位で設定できます。
     「全体」
     「行ヘッダ」
     「列ヘッダ」
     「列全体」
     「行全体」
     「奇数行」
     「セル個別」
    http://msdn.microsoft.com/ja-jp/library/1yef90x0%28VS.80%29.aspx

    これらは継承関係にあり、.HasStyle = False の場合は親のスタイルが使われます。
    また、.Style.Font = Nothing や .Style.BackColor = Color.Empty などとして、
    「背景色とフォントは親スタイルで、文字色だけ個別設定」のような事もできます。


    > セルごとにその都度バックカラー等同じものを設定すればできそうです。
    大量に個別設定すると、パフォーマンス上の問題を生じます。
    可能な限り、上位のスタイル(列単位など)で設定するようにしてください。

    もしもセルが連続していない場合でも、それぞれのセルのスタイルが同じ設定の場合は、
    DataGridViewCellStyle 型の変数を用意し、それを Style に渡すようにします(設定の共有)。

    また、スタイルがデータの内容に依存する場合(たとえば、マイナス値を赤くするなど)には、
    CellFormatting や CellPainting などでイベント処理した方が良いでしょう。


    余力があれば、このあたりも読んでおくと良いかも。
    http://msdn.microsoft.com/ja-jp/library/ha5xt0d9%28VS.80%29.aspx
記事No.57407 のレス / END /過去ログ96より / 関連記事表示
削除チェック/

■86407  空の delegate は null なの?
□投稿者/ 774RR -(2018/01/26(Fri) 14:18:29)

    分類:[C#] 

    なんだかすごく納得がいかないのですが、こういうものなのでしょうか?

    class test
    {
    int f(int x, int y) { return x+y; }
    delegate int delegate_ifii(int x, int y);
    delegate_ifii d;
    public test()
    {
    // メンバ宣言して new してない段階では d は null なのは納得
    d = new delegate_ifii(f); // ここで d が作られるのも納得
    d -= f; // デバッガ上 d が null となるのが理解不能
    // デバッガ上だけでなくて本当に null の様子
    if (d == null) System.Diagnostics.Debug.WriteLine("null");
    d += f; // null に対して += できるのが理解不能
    }
    }

    そういやオイラ event ハンドラにはいつも「何もしない」ハンドラを割り振ってますな。
    public event PnPEventHandler pnpEvent = delegate(object o, EventArgs e) { };
    割り振らないとエラーになるのはこの辺に原因があったのか・・・
親記事 /過去ログ148より / 関連記事表示
削除チェック/

■86408  Re[1]: 空の delegate は null なの?
□投稿者/ 774RR -(2018/01/26(Fri) 14:19:43)
    あう図表モードになってなかった・・・まあいいや適当にインデントしてください。
記事No.86407 のレス /過去ログ148より / 関連記事表示
削除チェック/

■86420  Re[2]: 空の delegate は null なの?
□投稿者/ furu -(2018/01/26(Fri) 17:54:04)
    No86408 (774RR さん) に返信
    
    まあ、特殊なんで
    
    public test()
    {
        d += f;        //d==nullでも落ちない
        d += f;
        d -= f;
        d -= f;        //dがnullになる
        d -= f;        //d==nullでも落ちない
    }
    
記事No.86407 のレス /過去ログ148より / 関連記事表示
削除チェック/

■86418  Re[1]: 空の delegate は null なの?
□投稿者/ WebSurfer -(2018/01/26(Fri) 17:42:32)
    No86407 (774RR さん) に返信

    > なんだかすごく納得がいかないのですが、こういうものなのでしょうか?

    最後の方にイベントとハンドラのことを書かれていますが、それと同じで、そういうものだと
    思います。

    ハンドラがアタッチされてない場合、イベントは null になるので、イベントを起動するメソ
    ッドではイベントが null でないことを確認した上で起動するというのがお約束になっている
    ということを Microsoft のチュートリアルで見た記憶があります。

    > d = new delegate_ifii(f); // ここで d が作られるのも納得
    > d -= f; // デバッガ上 d が null となるのが理解不能

    という操作は、ハンドラをアタッチして、同じハンドラをデタッチしているので、d が null に
    なるのは、少なくとも自分は理解できます。
記事No.86407 のレス /過去ログ148より / 関連記事表示
削除チェック/

■86425  Re[2]: 空の delegate は null なの?
□投稿者/ 774RR -(2018/01/26(Fri) 19:16:58)
    null は要するに null ですから(なんのこっちゃ)
    null でないオブジェクトを操作したら null になっちゃうあたりが超絶気持ち悪くて
    null に対して += できるあたりも心ふたぐのです。

    オブジェクトはあって中身が空 (List とか Dictionary とかでありがち) なら心落ち着くんですが。

    まあお二人が「そんなもの」と仰ってるので C# 業界ではそういうのもありなんだな、と現実逃避しときます。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86424  Re[2]: 空の delegate は null なの?
□投稿者/ Hongliang -(2018/01/26(Fri) 19:16:31)
    > d += f; // null に対して += できるのが理解不能
    演算子オーバーロードは静的メソッドなので、別に左辺がnullでも(型が許す限りは)問題ないです。
    stringでもnullに+=できます。
    string str = null;
    str += "a";
    Debug.WriteLine(str); // "a"
記事No.86407 のレス /過去ログ148より / 関連記事表示
削除チェック/

■86427  Re[1]: 空の delegate は null なの?
□投稿者/ 魔界の仮面弁士 -(2018/01/26(Fri) 20:58:05)
    2018/01/26(Fri) 21:01:15 編集(投稿者)

    # 解決済みマークはそのままにしておきます。

    No86407 (774RR さん) に返信
    > なんだかすごく納得がいかないのですが、こういうものなのでしょうか?

    糖衣構文を紐解いてみると、仕組みが見えてくるかもしれませんよ。


    前提知識として、C# のデリゲートは MulticastDelegate の派生クラスとしてコンパイルされます。
    // typeof(delegate_ifii).BaseType.ToString() == "System.MulticastDelegate"

    そして MulticastDelegate は System.Delegate の派生クラスです。


    > d = new delegate_ifii(f);

    C# 1.x では、デリゲートインスタンスの割り当ての際に
     d = new delegate_ifii(this.f);
    と書いていましたが、C# 2.0 以降では
     d = this.f;
    という糖衣構文でも書けるようになりましたよね。


    そして
    > d += f;
    これは要するに、
     d = (delegate_ifii)delegate_ifii.Combine(d, new delegate_ifii(f));
    の糖衣構文だったりします。


    そもそも、System.Delegate.Combine は、引数に null を渡すことを禁止していません。
    null が渡された場合の動作については下記を参照してください。
    https://msdn.microsoft.com/ja-jp/library/30cyx32c.aspx
    https://msdn.microsoft.com/ja-jp/library/b1eh4771.aspx


    このため、delegateInstance1 += delegateInstance2; という処理は、
    左辺「delegateInstance1」と右辺「delegateInstance2」の
    いずれかあるいは両方が null であったとしても、
    何の問題も無いというわけです。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86445  Re[2]: 空の delegate は null なの?
□投稿者/ 774RR -(2018/01/29(Mon) 19:06:38)
    おお non-static メンバ関数ではなくて static メンバ関数の syntax sugar だったわけですか・・・
    C++ では += が static メンバにはなりえないのでそういう認識でいました。
    違う言語を同一視するような時点でかなりアレなんですがなるほどです。
    # += が Combine の糖衣構文であるとはどこに書いてあるんだろう・・・探す気力なし

    this が必須のような構文をしておいて実は static っつーのはずいぶん罪作りな糖衣構文っすね。
    オイラもきっちり調べればこういう質問は出なかったのかもしれませんが調べきれませんでした。
    # C/C++ なら言語仕様書でも ReferenceSource でも調べたのですが
    # C# は本業ではないのでと逃げておく。

記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86453  Re[3]: 空の delegate は null なの?
□投稿者/ 魔界の仮面弁士 -(2018/01/30(Tue) 18:27:56)
    No86407 (774RR さん) に返信
    > そういやオイラ event ハンドラにはいつも「何もしない」ハンドラを割り振ってますな。

    それって、イベントを提供する側の話でしょうか。
    それとも、イベントを利用する側の話でしょうか。
     button1.Click += delegate {}

    いずれにしても、EventHandler や EventHandler<TEventArgs> に限った話ですよね。

    C# では、戻り値を返すイベントを定義できますが、
    この場合、「何もしない ハンドラ」を割り当てるわけには行かないはず。
     public delegate bool FooDelegate(int x);
     public event FooDelegate Foo;


    一方 VB.NET の場合、『戻り値を持ったイベント』を定義しようとすると
    Visual Basic ではコンパイルエラー(BC31084)となる仕様です。
    定義済みのものを利用する分には、VB6 でも VB.NET でも可能なのですが。


    実際のところ、複数のメソッド呼び出しを束ねるのはイベントの場合ぐらいで、
    ましてや戻り値を持つメソッドを連結させることは非常に稀だとは思いますが、
    もしも個々の戻り値を個別に受け取る必要がある場合は、そのデリゲートの
    GetInvocationList メソッドを利用できるようになっています。



    > // メンバ宣言して new してない段階では d は null なのは納得

    未初期化のローカル変数 d に対しては
     d = Method1;
    は実行できても、
     d += Method1;
    はコンパイルエラーになりますね(CS0165)。当然のことではありますが。



    No86445 (774RR さん) に返信
    > おお non-static メンバ関数ではなくて static メンバ関数の syntax sugar だったわけですか・・・

    ちなみにデリゲートは、インスタンスメソッドの呼び出しに最適化されているため、
    静的メソッドの呼び出しだと、効率がかなり悪いそうです。
    これについて、カリー化(curried delegate)で回避できます。
    http://ufcpp.net/study/csharp/functional/miscdelegateinternal/


    > C++ では += が static メンバにはなりえないのでそういう認識でいました。
    > this が必須のような構文をしておいて実は static っつーのはずいぶん罪作りな糖衣構文っすね。

    delegate 以外でも、
     string s = null;
     s += null;
    と書けますけれどね。しかも上記の結果は、null ではなく string.Empty です。

    # 上記は『s = System.String.Concat(null, null);』相当


    > # += が Combine の糖衣構文であるとはどこに書いてあるんだろう・・・探す気力なし

    同じ意味になると、大昔に TechEd あたりで聞いたような気がするのですが、
    済みません、私もうろ覚えなので情報ソースは提示できないです。

    公式資料として書いたものがあるかどうかまでは分からないので、
    糖衣構文と呼べるかどうかは自信がなくなってきました。今更ですが。


    ただ言語仕様面で捉えてみると、+= が Combine というよりは、
    「a += b」が「a = a + b;」の糖衣構文と捉えた方が良いかと思っています。

    「変数 a」の型が、「a + b」の演算が返す型と同じ(あるいは暗黙変換可能)でない場合、
    a += b; はコンパイルエラーとなります。

    // これはエラー
    int a = 0;
    a += 0L;

    // これは OK
    float b = 0F;
    b += 0L;


    ただしデリゲートが event 化されている場合は話が変わってきます。

    イベントは特別扱いされており、デリゲート型変数とは違って、
    演算子として += と -= しか使えません。(デリゲートなら + や - や = も使える)
    しかも代入式の左辺にしか記述できないという制限付き。

    この制限があるため、匿名メソッドやラムダ式を、
     button2.Click += delegate { MessageBox.Show("Test"); };
    のように、変数を介さずにイベントハンドラとして直接割り当ててしまうと、
    後で解除あるいはクリアできずに難儀することになりますね。


    ちなみに上記の += 処理は、
     button2.add_Click(new EventHandler(delegate { MessageBox.Show("Test"); }));
    相当の処理としてコンパイルされます。

    といっても、C# からの add_Click メソッドの呼び出しは禁止されているのですけれども。
    (JScript.NET や PowerShell の場合は、add_Click メソッドを使って割り当てます)
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86454  Re[4]: 空の delegate は null なの?
□投稿者/ 774RR -(2018/01/30(Tue) 19:22:51)
    > それって、イベントを提供する側の話でしょうか。
    提供する側っす。
    提供する側は常にいる(通信スレッドがいつも走っていてデータ受信のたびにイベントを起こす)
    利用する側は常にいるとは限らない( UI スレッド / Form 側は「モニター停止」状態)
    なんてときに event handler に -= をしたくなるのですが、提供する側は null チェックなんぞしたくないので
    無条件で event を発行するためには「何もないハンドラ」を最初からくっつけちゃうと善哉。

    delegate って this+関数ポインタ と単純な割にはすっごく便利で C++ にも標準で欲しかった感じ。
    まあ自作してもそんなに難しくないしウチの新人君の課題に出してみよう。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86456  Re[5]: 空の delegate は null なの?
□投稿者/ 魔界の仮面弁士 -(2018/01/30(Tue) 20:01:46)
    2018/01/30(Tue) 20:02:37 編集(投稿者)

    No86454 (774RR さん) に返信
    > なんてときに event handler に -= をしたくなるのですが、提供する側は null チェックなんぞしたくないので
    > 無条件で event を発行するためには「何もないハンドラ」を最初からくっつけちゃうと善哉。

    コスト的には、null 条件演算子を使った方がお奨めです。

    // 要 C# 6 以降
    public event EventHandler ThresholdReached;
    protected virtual void OnThresholdReached(EventArgs e) { ThresholdReached?.Invoke(this, e); }
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86459  Re[4]: 空の delegate は null なの?
□投稿者/ furu -(2018/01/30(Tue) 22:05:06)
    2018/01/30(Tue) 22:05:52 編集(投稿者)
    2018/01/30(Tue) 22:05:43 編集(投稿者)



    No86453 (魔界の仮面弁士 さん) に返信
    > ただ言語仕様面で捉えてみると、+= が Combine というよりは、
    > 「a += b」が「a = a + b;」の糖衣構文と捉えた方が良いかと思っています。

    言語仕様(JIS規格X3015:2008)では、x op= yは

    x op yの演算の結果がxの型に暗黙に変換される場合、x = x op y
    x op yの演算の結果がxの型に明示的に変換され、yがxの型に暗黙的に変換される場合、x = (T)(x = x op y)
     ※Tはxの型,仕様にはシフト演算子の場合の記述もある

    >
    > 「変数 a」の型が、「a + b」の演算が返す型と同じ(あるいは暗黙変換可能)でない場合、
    > a += b; はコンパイルエラーとなります。

    byte b = 0;

    b += 1; //OK
    b = b + 1; //エラー

    b <<= 1; //OK
    b = b << 1; //エラー

    また、x op= y が x = x op yと決定的に違うのは、xの評価が1度だけだということが保証されています。

    int[] x = new int[100];
    x[new Random().Next(100)] += 7; //new Random().Next(100)は、1度だけ計算

    > ただしデリゲートが event 化されている場合は話が変わってきます。

    言語仕様で、通常の+=,-=は、「複合代入」ですが、イベントの場合「イベント代入」となっていて
    まったくの別物として定義されてますね。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86460  Re[5]: 空の delegate は null なの?
□投稿者/ Azulean -(2018/01/30(Tue) 23:12:36)
    2018/01/30(Tue) 23:50:01 編集(投稿者)

    No86459 (furu さん) に返信
    > 言語仕様(JIS規格X3015:2008)では、

    あまり知られていないかもしれませんが、Visual Studio のインストール先の VC#、Specifications 以下に Word で C# 言語仕様書が入っているんですよね。
    なので、JIS を見に行かなくても HDD に大抵あるんです。
    (ただし、5.0 なので最新の言語仕様書ではない)

    「7.17 代入演算子」とか「7.17.2 複合代入」とかですかね、今回の場合。


    // イベントアクセスは event キーワードで定義された add/remove があるものを指していると思われるので、デリゲートは別ですね。
    // 「10.8.1 フィールドのように使用するイベント」あたりで説明されているものだと考えています。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86461  Re[6]: 空の delegate は null なの?
□投稿者/ furu -(2018/01/31(Wed) 09:42:28)
    No86460 (Azulean さん) に返信
    > 2018/01/30(Tue) 23:50:01 編集(投稿者)
    >
    > ■No86459 (furu さん) に返信
    >>言語仕様(JIS規格X3015:2008)では、
    >
    > あまり知られていないかもしれませんが、Visual Studio のインストール先の VC#、Specifications 以下に Word で C# 言語仕様書が入っているんですよね。
    > なので、JIS を見に行かなくても HDD に大抵あるんです。
    > (ただし、5.0 なので最新の言語仕様書ではない)

    Azulean さん、ありがとうございます。ずっと探していました。
    ここでも以前に質問したりしたんですけど、いつの間にかこんなところにあるとは。
    HDDは手元のJISの本よりちょっと遠いですが、いろいろ便利になります。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/

■86462  Re[7]: 空の delegate は null なの?
□投稿者/ Azulean -(2018/01/31(Wed) 12:27:13)
    No86461 (furu さん) に返信
    > ここでも以前に質問したりしたんですけど、いつの間にかこんなところにあるとは。

    少なくとも 2005 の時点で存在していました。
    以降、ずっとあるはずですが、認知度は低いのですよね。
記事No.86407 のレス / END /過去ログ148より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -