[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2ch.scのread.cgiへ]
Update time : 05/12 07:11 / Filesize : 279 KB / Number-of Response : 1029
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C#, C♯, C#相談室 Part91



1 名前:デフォルトの名無しさん [2016/06/29(水) 04:39:09.19 ID:sT3gw8va.net]
■Visual Studio 2013 Community & Express(無償の統合開発環境)等はこちら
www.visualstudio.com/downloads/

■コードを貼る場合はこちら
ideone.com/

■前スレ
C#, C♯, C#相談室 Part88 [転載禁止]©2ch.net
peace.2ch.net/test/read.cgi/tech/1437808445/
C#, C♯, C#相談室 Part89
peace.2ch.net/test/read.cgi/tech/1443271409/
C#, C♯, C#相談室 Part90
echo.2ch.net/test/read.cgi/tech/1455160063/

■次スレは>>970が建てる事。
建てられない場合は他を指定する事。

321 名前:デフォルトの名無しさん mailto:sage [2016/08/18(木) 19:24:39.04 ID:zEQl8UVs.net]
OutOfMemoryに限らずデバッガで該当する場所でなくエントリポイントが表示されたり
GDI+関連のエラーだと意図していない場所のRefresh()とかで止まることならある
try-catchを入れとけばそこで表示されるから済む話だが

322 名前:デフォルトの名無しさん mailto:sage [2016/08/18(木) 19:33:28.84 ID:CKZSwyTz.net]
>>306
そう
前はふらっとにいたけどワッチョイ付いたら他の板での書き込みバレるからこっち来た

323 名前:デフォルトの名無しさん mailto:sage [2016/08/18(木) 20:03:39.26 ID:oJeK6Bjx.net]
cppでアウトオブメモリー処理のために汎用メモリーを取っておくシステムを見たことあるがそこまでやるべきなのか

324 名前:デフォルトの名無しさん mailto:sage [2016/08/25(木) 23:14:01.46 ID:HsD7PkbO.net]
What’s New in C# 7.0
https://blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

325 名前:デフォルトの名無しさん mailto:sage [2016/08/25(木) 23:42:36.74 ID:MmwMpV4v.net]
>>312
throw式以外は全部ボツだろうなこれ
ジャストアイデアとしても酷すぎ

326 名前:デフォルトの名無しさん mailto:sage [2016/08/25(木) 23:57:25.92 ID:Pgok0gcb.net]
>>313
タプルとパターンマッチング

327 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 00:02:49.66 ID:TYI3AeP1.net]
>>314
なんだよ。かまわんよ、存分にそれらについて語ってくれよ…

328 名前:デフォルトの名無しさん [2016/08/26(金) 00:04:14.57 ID:cD5Ga51Z.net]
>>312
tupleとdeconstructionは欲しいな

329 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 00:26:51.57 ID:qEbjB0B4.net]
C#7.0はいい感じだね
早く業務で使いたい



330 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 00:32:45.54 ID:zWe+Xnw2.net]
パターンマッチはdeconstructionと組み合わせられないとほとんど意味ない、
というかOCPを破るだけで有害
やるなら最初からやらないとこんな中途半端なもの出したら
コーディング規約で軒並み禁止されちゃうぞ

331 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 00:39:32.65 ID:TYI3AeP1.net]
プロパティ禁止とか最早ブラックあるあるネタだもんな…今更感はある

332 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 00:48:13.71 ID:PgCAqldG.net]
>>319
そもそもプロパティを知らないおっさんがいて驚いたわ

333 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:01:05.00 ID:b/aYUiUZ.net]
getX(),setX()書く人は、まれに良く紛れ込むね

334 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:13:44.01 ID:ZXi/bCeq.net]
.NET4.0とC#7の組み合わせって可能なのかなあ。
まだあと5年ぐらいはXPのPC無視できないよね。

335 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:18:27.62 ID:PgCAqldG.net]
>>322
4.0とかとっくにサポート切れやで

336 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:27:27.85 ID:AjmVo6xU.net]
>>321
それがうちのルールなう

337 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:29:19.51 ID:MwmpSlTr.net]
カワイソス

338 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:35:14.31 ID:b/aYUiUZ.net]
>>324
残念すぎる(

339 名前:LД`) []
[ここ壊れてます]



340 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 01:56:48.53 ID:iK8FV/yi.net]
>>322
ウチはWindows2000(.NET 2.0)も無視できない場合がある。
設備制御用のスタンドアローン機だが。

341 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 17:37:43.90 ID:MxDOiAHv.net]
よくわからないけどパターンマッチングってどういう局面で必要?
いままでのコーディングが大幅に減るとかいい面を教えてほしい
今のところ見にくいなあと感じる

342 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 18:46:17.17 ID:zWe+Xnw2.net]
>>328
本格的なパターンマッチングならこんなことができる
double GetArea(Shape shape) {
switch (shape) {
case Rectangle(x,y,w,h): return w * h;
case Circle(x,y,r): return PI * r * r;
}
}
さらに、変数にキャプチャするだけでなくxに具体的な値を指定すればxが特定の値の場合だけという条件指定も可能
今の貧弱な仕様だとお前の疑問の通りメリットはほとんどないのでまあ最終的には却下だろうな

343 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 20:21:13.42 ID:6mUdfhCy.net]
オブジェクト指向からswitch地獄に退化してないそれ?
関数型とかだとそれが普通なのかな

344 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 21:28:47.03 ID:MxDOiAHv.net]
必要に応じて使わないと退化だな

345 名前:デフォルトの名無しさん mailto:sage [2016/08/26(金) 22:32:43.70 ID:zWe+Xnw2.net]
関数型はあくまで関数が主だからね
(本物の)パターンマッチは静的検査でパターンの網羅性を担保できるから、
やってることはインターフェースを実装してるのと同じようなもん

346 名前:デフォルトの名無しさん [2016/08/27(土) 00:18:55.08 ID:nVNQ8rj/.net]
この場合は単純にGetAreaをabstract methodにして
各クラスでoverrideさせた方がよくないっすか?

347 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 00:20:04.19 ID:1AQozIyW.net]
if(x > y) (x, y) = (y, x);

348 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 00:38:01.47 ID:gXVhUUHW.net]
>>333
その方がいいと思う理由は?
>>333にとって関数型よりオブジェクト指向の方が馴染みがあるからそう感じるだけじゃない?
どっちがいいかじゃなくて考え方が違うんだよ

349 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 00:57:01.73 ID:p93C1zWb.net]
C#は関数型言語を目指すのか?



350 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 00:58:08.99 ID:dfJ7JP1w.net]
>>336
良いとこを取り入れようとしている

351 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 01:26:03.53 ID:zYdR+KfD.net]
マルチパラダイム言語なんだから、あるプログラミングパラダイムには大して効果的でない
(が、他のプログラミングパラダイムでは効果的な)機能が入ることもあるさ

352 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 01:43:46.91 ID:p93C1zWb.net]
まあたしかに今のC#はマルチパラダイムなんだろうけど
そもそもマルチパラダイムを意識して設計された言語なのだろうか

良いとこ取りしようって考え方はいいんだが
マルチパラダイムで複数のスタイルに対応しようとか、言語の複雑さが増すだけだと思うんだがなぁ

まあそのうち、オブジェクト指向でやりたい人はこれは不要(というか使うな)とかいう機能と
関数型でやりたい人はこの機能は使うなとかいう分類が出来ていくのだろうかね
だったら初めから言語分けろよと思うわけなんだが

353 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 08:01:26.33 ID:uwQm2EgT.net]
このままではVB6になってしまう

354 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 08:50:02.94 ID:ZCfqwLYC.net]
>>330
switchで分岐して分かりやすいと思う

355 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 08:50:57.27 ID:ZCfqwLYC.net]
>>333
switchがいい

356 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 08:59:36.29 ID:xPu9ULSF.net]
パターンマッチングは大変な事になりそう
ようするに型を調べて分岐の糖衣構文でしょ
バッドプラクティスの糖衣構文なんてよくないよ

357 名前:デフォルトの名無しさん [2016/08/27(土) 09:04:35.71 ID:SmFG8gRK.net]
      ク    ク || プ  //
      ス  ク ス  | | │ //
       / ス    | | ッ //   ク   ク  ||. プ  //
       /         //   ス ク ス _ | | │ //
         / ̄ ̄\     /  ス   ─ | | ッ //
       /  _ノ  .\     /         //
       |  ( >)(<)       ___
.        |  ⌒(__人__)     ./ ⌒  ⌒\
        |    ` Y⌒l    /  (>) (<)\
.         |    . 人__ ヽ /  ::::::⌒(__人__)⌒ \
        ヽ         }| | |        ` Y⌒ l__   |
         ヽ    ノ、| | \       人_ ヽ /
.         /^l       / /   ,─l       ヽ \

358 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 09:18:21.32 ID:xncZCRpk.net]
ポリモフィズム過負荷で歪なクラスを量産するよりはよい

359 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 09:56:58.93 ID:gXVhUUHW.net]
型で分岐するのがどうして問題かというと、
後で型を追加したときに分岐の箇所を自分で探して条件を追加しなきゃいけなくなるから。
ちゃんとした関数型だと、パターンマッチで分岐させるような型って
type Shape = Rectangle(double x, double y, double w, double h)
  | Circle(double x, double y, double r);
みたいな感じでクローズしておくんだよ。
これでShapeがとりうる全ての型をコンパイラが認識できるから、
Shapeに型を新たに追加したら>>329がコンパイルエラーになってくれる。
イメージ的には 列挙体 + タプル に近いかな。OO言語の超強力なクラスとは全然異なるもの。
このように、パターンマッチは根が深いからにわか言語が中途半端に導入するとおかしなことになる。



360 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 10:14:58.12 ID:xncZCRpk.net]
データベースやXMLで不定形データ受け取って
パースした後の分岐に使うくらいかな

361 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 10:17:36.05 ID:xPu9ULSF.net]
>>346
モジュールの配布面倒くさそう
パターンをを追加したら参照元コード全部追記してねって全ユーザーに通知するの?

362 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 12:08:15.98 ID:vp5ltHnS.net]
>>346
しかしそれだと書く側にとってはOOPの方がいいが。

機能追加がクラス追加で対応できるとき、
OOP: 既存部分に一切手を入れる必要はない。
FP: 既存部分も書き直す必要がある。

普通はどう見ても退化だよ。
書き直す部分がSyntaxErrorで見つかるのは便利だけど、
OOPでもそのクラスの全メソッドを列挙するのは簡単なので、漏れる事もない。

OOPは実際の詳細なクラス毎の動作はその部分のコードからは読みとれない。
それがswitchの方がいいという人の意見なのだろうけど、
大概の場合は読みとれないのは低位記述のみであって、読みとる必要がないから問題ない。

>>329にしてもGetAreaメソッドの方がいいし、
本家の例にしてもExplainMyselfメソッドの方がいい。
本来はメソッドとしてくくれないswitch分岐に使えばいいのだろうけど、
本家にしてもそのいい例を探せなかったということじゃないか。
つまり要らない子。

363 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 18:13:53.32 ID:gff3j1Ec.net]
C#はjsのオブジェクトリテラルを導入すべきだ
C#の匿名型は書きにくいし見辛い

364 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 19:31:49.76 ID:p93C1zWb.net]
つまりパターンマッチはオブジェクト指向とはきわめて相性が悪いって事か
まあ、型チェックと代入が一発でできる機能だけなら便利に使える場面もあるだろうけど

365 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 19:54:25.56 ID:0MFbcQeG.net]
相性が悪いんじゃなくて使い分けだと思う

上ででたShapeでは各クラスが面積を出すメソッドを持っててもべつにいいだろうけど
GUI側で図形の表示に使うメソッドをShapeに持たせるのはおかしい

その場合はどこか別

366 名前:で限定的にこのパターンマッチを使えばいいのではないか? []
[ここ壊れてます]

367 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 19:54:53.32 ID:vp5ltHnS.net]
相性が悪いわけではなく、用途がないんだと思う。

型ありOOPの場合は、型判定+分岐を仮想関数で対応するのが基本思想である為、
そもそもの例がswitch文で型判定の時点で要らない子でしかない。
もうちょっとマシな例はなかったのかよ、とも思うが。

つかどっちかというと、
パターンマッチングが活躍している言語のソースを眺めた方が良いのではないか?
誰か知ってたら教えてプリーズ。

368 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 20:00:45.28 ID:vp5ltHnS.net]
あ、ただ、絞り込みは出来るようだから、それは役に立つか?

> case Rectangle s when (s.Length == s.Height):
> case Rectangle r:

もちろんメソッドでも出来るが、色々まどろっこしくなるのかも。
(俺はC#erではないので詳しくは分からない)

369 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 20:33:04.97 ID:vp5ltHnS.net]
>>352
> GUI側で図形の表示に使うメソッドをShapeに持たせるのはおかしい
言っていることは分かるけども、それは思想によると思うよ。

OOP原理主義だとして、GUI側からの描画リクエスト対応もメソッドとして持たせた場合、
オブジェクトのメソッドは永遠に追加されていくことになるので、オブジェクトのソースが確定しない。
でも、OOPの基本理念、「動作しているコードには一切触れることなく機能追加可能」は実現出来る。
したがって、デグレードの危険が全くない。

機能の切り分けとしてはGUI側に持たせたいところだけど、
これだと追加Shape毎にGUI側もいちいち対応しないといけなくなる。
(動いているコードを修正する必要がある)

オブジェクトが肥大化するけども、
バグを出さない為の管理なら、オブジェクト側に持たせた方が楽だと思う。
他プログラムとオブジェクトを共用する気なら、
オレオレメソッドで肥大化したオブジェクトなんて要らないから、
GUI側に持たせることになる。

もしかして拡張メソッドってこのため?アレいまいちピンとこなかったんだが。



370 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 21:12:00.13 ID:n0Zp8t3m.net]
Shapeのコンテキストによるだろ
数学や物理の計算に使うモデルなら描画用メソッドなんて書いた時点で解雇されるし
描画モデルなら描画用メソッドがあってもいい

371 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 21:43:02.69 ID:vp5ltHnS.net]
だからそのための拡張メソッドじゃないの?
今回の例なら、GUI側で拡張メソッドを追加して対応する。
すると、既存コードに手を加えることもなく、描画部分もswitch文無しという、両取りが可能。
追加Shapeがあった時もGUI側の拡張メソッド部分に追加するだけ。管理もしやすい。
https://msdn.microsoft.com/ja-jp/library/bb383977.aspx

372 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:01:19.98 ID:gXVhUUHW.net]
>>357
それは詭弁だな
拡張メソッドは単に型ごとにGetAreaをオーバーロードしてるだけだ
オブジェクト指向というよりはむしろ関数型的なやり方
型switchや仮想メソッドは実行時型に応じた動的な多相を実現する手段で、拡張メソッドで代替できるものではないよ

373 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:23:19.62 ID:E9zwljSJ.net]
>>357
今の流れに拡張メソッド全く関係ないよね

374 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:23:59.95 ID:vp5ltHnS.net]
>>358
> 実行時型に応じた動的な多相
C#には無いだろこれ。

375 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:37:21.41 ID:gXVhUUHW.net]
>>360
?
普通にメソッドのオーバーライドによる多態のことだよ

376 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:42:35.41 ID:vp5ltHnS.net]
>>361
例えばJavaScriptでは動的に型を変更出来る。
だから実行時にswitchでやるのとコンパイル時に静的にリンクするのでは動作が異なってくる。
そういうのはC#にはないでしょ、って話。

だから話を戻すと、>>329のケースは通常のOOPの多態、
>>352のケースは拡張メソッドが一番良いと思う。
本家のも普通はOOPで対応する。
ただそれだと例にならないのでクエリがわざわざくっつけられているのだと思う。

377 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 22:43:28.66 ID:yK/3tXKV.net]
何の話を

378 名前:してるのかなってちょっと上からレス読んでみたけど、
>>352の話ならShapeがDrawを持っても別に必ずしもおかしくないし、
持たせたくないならShapeで描画側が要求する描画に必要なデータを提供する
一連のメソッドやプロパティを定義しておけば済む話だよね。

描画側で型を見て分岐なんてどう贔屓目に見ても最悪のやり方にしか思えんね俺も。
[]
[ここ壊れてます]

379 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:01:52.80 ID:gXVhUUHW.net]
>>362
最初の4行は俺にはよく意味がわからないけどそれはまあいいとして、
>>329で多態が必要なのに>>352は拡張メソッドでいいというのは矛盾してるよ。
List<Shape>に入ってるものを全部Drawしたいとき、型ごとの拡張メソッドじゃ対応できないよ?
Shapeの外部にメソッドを定義しつつ多態相当の動作をさせたい、そのうえ明示的な型判定はダメというんなら、
引数をdynamicにキャストして強引に動的ディスパッチさせるみたいなことが必要。



380 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:02:26.56 ID:ygls7M0s.net]
>>363
おかしいかおかしくないかは場合による
このShapeが幾何学計算ライブラリのShapeだったらDrawはおかしい
図形描画用のライブラリならDrawがあってもおかしくないしなくてもおかしくない

381 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:10:16.02 ID:vp5ltHnS.net]
>>364
> List<Shape>に入ってるものを全部Drawしたいとき、型ごとの拡張メソッドじゃ対応できないよ?
出来るよ。というかそちららの認識が間違っていると思うが、
拡張メソッドはソース上では普通のメソッドと見た目は同じだよ。

382 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:15:37.10 ID:ygls7M0s.net]
>>366
ネタかマジかからかってるかわからないんだけど

383 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:18:51.07 ID:gXVhUUHW.net]
>>366
ほんとに?
https://ideone.com/lmc8TO
たまには自分の思い込みを疑ってみるのも大切だぞ

384 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:19:50.69 ID:vp5ltHnS.net]
>>364
>>367
いやこちらも意味不明なのだが。
逆に>>364の言う「メソッドでは対応出来るが拡張メソッドでは対応出来ない」ケースって出せるか?

385 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:28:42.22 ID:vp5ltHnS.net]
>>368
いやそれOOPじゃないと思うが、、、ただのオーバーロードだよね。

386 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:31:52.50 ID:gXVhUUHW.net]
>>370
だから俺は>>358からそう言ってるじゃん
拡張メソッドでは対応できないケースを示しただろ?

387 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:33:00.29 ID:ygls7M0s.net]
>>369
拡張メソッドにできない事、のシンプルな答えとして挙げるなら、インスタンスメソッドにはなれない、だな
それでもう終わりだろこの話
わからないなら入門書読み直してくれ

388 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:40:42.34 ID:vp5ltHnS.net]
>>371,372
まあ俺はC#erではないので拡張メソッドは使ったことがないし、
俺の理解が間違っている可能性もあるが、
MSDNの仕様書を見る限り、当たり前だがメソッドを拡張したように見せかけているのだと思うよ。
だからその場合は Rectangle と Circle に対して拡張メソッドを追加する。
これができないのならそちらの言うとおりだが、それだと拡張メソッドなんてゴミじゃん。

まあどのみち俺かそちらの仕様に対する勘違いだと思うので、この話はこれで終わりでいい。

389 名前:デフォルトの名無しさん mailto:sage [2016/08/27(土) 23:48:05.17 ID:vp5ltHnS.net]
>>372
いや悪いがやっぱりそっちが間違ってるぞ。
拡張メソッドで普通にthisが取れてる。(引数の所に書く)
つかそうじゃないと意味無いだろ。

> public static int WordCount(this String str)
> {
> return str.Split(new char[] { ' ', '.', '?' },
> StringSplitOptions.RemoveEmptyEntries).Length;
> }
> https://msdn.microsoft.com/ja-jp/library/bb383977.aspx



390 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:08:50.44 ID:s1SxoEZK.net]
>>374
あんたにも分かるように説明してあげよう
拡張メソッドとは、HogeClass.func(x) を x.func() と書けるシンタックスシュガーである
そ れ だ け

391 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:15:50.55 ID:zGC1w6Ia.net]
>>365
だからそう言ってるでしょ。

392 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:17:10.42 ID:+mkoP4gZ.net]
>>375
それはオブジェクト指向がその意味でのシンタックスシュガーでしかないよ。
class構文が無かったCでも関数ポインタ+構造体で同じ事が出来たわけだし。

重要なのは拡張メソッドにthisが渡っていることだよ。
静的メソッド(クラスメソッド)にはthis使えないでしょ。
今回の例で言えば、宣言部分は以下になるということ。
ただしコンパイルが通るかどうかは知らんが。
通らないのなら君の言うとおり、通るのなら俺の言い分が正しいことになる。

public static void Draw(this Rectangle rect)
public static void Draw(this Circle circle)

393 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:19:39.62 ID:UJTSRlJK.net]
何で拡張メソッドってstaticクラスじゃないと定義出来ないんだ?
何か理由あるの?
別に制限はstaticメソッドだけでいいと思うけど

例えばString.IsNullOrEmpty(String)
もしstaticクラス以外に拡張メソッド定義出来たら
String.IsNullOrEmpty(this String)
みたいになって更に便利になると思うのに

394 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:21:24.05 ID:hQF+q+Zk.net]
そこのthisは単に拡張メソッドのマーク
通常のthisとは違う意味

拡張メソッドは親クラスからは呼べないからそれを定義してもShapeクラスから直接呼べない
RectangleやCircleにキャストすることになる
そこで登場するのがパターンマッチングと

395 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:26:26.11 ID:UJTSRlJK.net]
今更変えるのは互換性的な問題で難しいだろうけど、
==演算子を等価演算子
===演算子を等値or不変インスタンスかつ等価演算子
にするべきだと思った
不変かは属性とかで定義して
Equalsメソッドとかいらねーだろ
==演算子と両方定義しろとかどうなってんだ

396 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:31:26.64 ID:+mkoP4gZ.net]
>>379
いや拡張メソッド内で自分自身のメンバを参照出来るよ。多分。

> 実際に、拡張メソッドは、それらが拡張している型のプライベート変数にはアクセスできません。
> https://msdn.microsoft.com/ja-jp/library/bb383977.aspx

普通に考えれば、わざわざプライベートは駄目って書いてある時点でpublicならいけるって事でしょ。
要するに外面的には Draw(circle) でしかないところを circle.Draw() と書けるだけでしかない。
その辻褄はコンパイラが合わせるけど、privateをpublicには出来ないのでこれは無理。
MSDNの説明には矛盾を感じないけど。

397 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:36:48.79 ID:+mkoP4gZ.net]
>>379
> 拡張メソッドは親クラスからは呼べないからそれを定義してもShapeクラスから直接呼べない
バインディングはコンパイル時だし、多分普通に呼べると思うよ。
というか呼べないと拡張にならないから、文法が違ったとしても何らかの呼び方は必ずあるはず。

398 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:37:11.60 ID:zGC1w6Ia.net]
>>380
EquqlsというかIEquatableが不要とは思わないけど、
VBと同じように参照等価検査専用の演算子を用意して、==はオーバーロードしないと
使えないようにしてくれた方が分かりやすかったね。

399 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:43:30.59 ID:hQF+q+Zk.net]
>>379
RectangleとCircleにDraw拡張メソッドが定義されているなら以下のようになる
void hoge( Shape shape )
{
//できない
//shape.Draw();
if(shape is Rectangle)((Rectangle)shape).Draw();
else if(shape is Circle)((Circle)shape).Draw();
}

拡張メソッドを呼び出すときにキャスト必須

「Shapeを継承したクラスはすべてDraw拡張メソッドを定義しなければならない」
という条件はかなり強引で、ヘタすればCLRや共通言語仕様にも手を入れなければいけない問題になる



400 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:45:09.67 ID:s1SxoEZK.net]
>>378
スコープが広がってルールが複雑になるから
例えばこういうときどうする?
/* ファイル1.cs */
namespace NS1 { class Hoge { public static void EX(this Hoge h) { … } }
/* ファイル2.cs */
namespace NS2 { class Test { public static void Main() { new NS1.Hoge().EX(); } } }
これ、現在の仕様から類推すればファイル2内ではNS1をusingしてないから
EXは拡張メソッドとして呼び出せないはずだけど、直感的には呼べた方が自然だと思わない?
それとか、拡張メソッドを含むクラスを別の名前空間のクラスが継承したらどうする?

401 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 00:59:15.28 ID:hQF+q+Zk.net]
>>382
拡張メソッドはコンパイラで解決しなきゃいけない
しかし、外部のDLLがShapeの子クラスを実装して、それを動的に読み込む可能性があるのでコンパイラでは解決不能

>オブジェクト指向がその意味でのシンタックスシュガーでしかないよ
そういうことを言ってるんじゃない
オブジェクト指向は共通言語仕様に書かれているのでILにその情報が残り、すべての言語が対応する
それに対しシンタックスシュガーはコンパイラの機能でILに完全には残らなかったり、属性をつけることで対応しているコンパイラのみが利用する

402 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 01:12:12.64 ID:+mkoP4gZ.net]
>>386
コンパイラ云々は俺は普通に出来ると思っているのだが、まあそれは置いておこう。

>>384
こちらを先にやろう。

> //できない
> //shape.Draw();

これって出来ないんだっけ?というかこちらは最近はJavaScript(型無し)でやっていて、

void hoge(var shape ) // var なので何でも入る
{
shape.Draw(); // 勝手に直近のvirtualが呼ばれる。
}

で普通にオーバーライドされたvirtualが呼べる(circle.drawなりrectangle.drawなり)から、
実際のC#での記述の仕方は知らない。
ただ、アップキャストしたらもう仮想関数は呼べません、ダウンキャストしてからにしてください、
だとOOPとしてはかなり無理があるから、自然なやり方がないわけ無いと思うけど。
だってその is 構文ってのも新しいんでしょ?
だったらそれがなかったこれまではOOPできませんでしたーってことになっちゃうじゃん。

403 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 01:32:13.31 ID:hcj7YQtW.net]
しつけえなあ
入門書ぐらい読んでからにしろよ
なんでど素人がそんな自信満々なんだよ

404 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 01:33:21.98 ID:+mkoP4gZ.net]
>>384
以下見る限り、virtual付けたら普通にOOPできるとしか読めないが。
てか当たり前だが。
引き数渡ししたら出来なくなるって事もないと思うけど。

> しかし、動的な型に基づいて呼び出されるメソッドを決定したい場合があります。
> (というより、ほとんどの場合、メソッド呼び出しは動的に決定した方が都合がいい。)
> 動的な型に基づいて呼び出されるメソッドを選びたい場合、
> 以下のように、 メソッドに virtual という修飾子を付けます。
> ufcpp.net/study/csharp/oo_polymorphism.html
その上にvirtual付けなかった場合も書いてあるから見比べれば分かると思うよ。

405 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 01:37:09.54 ID:+mkoP4gZ.net]
>>388
まあその通りだ。今は最新環境がないので試せない。
確かにこれ以上やっても意味無いので、後日最新環境で試せば良いだけだね。
「拡張メソッド」ってのに俺が夢を見すぎているのかもしれんし。

406 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 02:08:02.18 ID:hQF+q+Zk.net]
>>389
何度も行っているように、拡張メソッドではオーバーライドできない。
なぜなら拡張メソッドはただのC#限定のstaticメソッドのシンタックスシュガーに過ぎないから。
そのURLではどこにも拡張メソッドのことは書いてないでしょ

class Triangle : Shape{}
ってプラグインみたいに外部のDLLで宣言されて、それを動的に読み込んで、hogeに渡ってきたらどうするの?
外部のDLLのことなんてコンパイルの地点では知らないので存在しない拡張メソッドを呼べるはずがない。

夢を見すぎているんじゃなくて、ただ無知でC#とかCLIをよく理解してないだけだと思う
javascriptで言うならprototypeの存在も知らないでjavascriptはウンタラカンタラ言っている状態なので、基礎から学び直したほうがいい

407 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 08:45:51.40 ID:UJTSRlJK.net]
>>385
そういう事か…確かに面倒だな
それならnull可メソッド的な物を作ればいいんじゃない

public null void Hoge(){
  //thisがnullの可能性あり
}

408 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 09:58:20.62 ID:+mkoP4gZ.net]
>>391
試したぞ。VS

409 名前:Community2015はサインインしないと使えなかったから、VS2008EEだが。
その範囲では確かに出来なかった。コードは以下ページを参考に改変した。
> http://ichitcltk.hustle.ne.jp/gudon2/index.php?pageType=file&id=cs002_ExtensionMethods
しかし理由は拡張メソッドがstaticだからだよ。以下コードで、

class SampleClass1 {}
class SubClass : SampleClass1 {}
static class hoo
{
static public void SampleExtensionMethod1(this SampleClass1 sampleClass1)
{
Console.WriteLine("super_ex");
}
static public void SampleExtensionMethod2(this SampleClass1 sampleClass1)
{
Console.WriteLine("super_ex2");
}
static public void SampleExtensionMethod1(this SubClass subClass)
{
Console.WriteLine("sub_ex");
}
}
static void test(SampleClass1 sampleClass1)
{
sampleClass1.SampleExtensionMethod1(); // (A)
sampleClass1.SampleMethod1(); // (B)
}
static void test3(SubClass subClass)
{
subClass.SampleExtensionMethod2(); .// (C)
}
[]
[ここ壊れてます]



410 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 09:59:05.95 ID:+mkoP4gZ.net]
(B)は通常メソッドで、SubClassが与えられると当然SubClassのメソッドが呼ばれる。
ただし(A)は常にSampleClass1(親クラスというより「そこに記述された」クラス)の拡張メソッドが呼ばれる。
なお(C)はSampleClass1の拡張メソッドが呼ばれる。
(つまり子→親に関しては辿れる)

(B)が動作する以上、thisポインタは正しく渡っている。
あとは拡張メソッド側に継承関係を明記し、実行時型でこれを解決すれば良いだけなのだけど、
C#はどうやら文法的にこれを禁止している。(技術的には全く問題なく出来るはず)

今回出来ないのは、拡張メソッドがstaticだからコンパイル時にそこにリンクされるからだ。
そこでvirtual指定してみたが、これはSyntacErrorで落ちる。
どうやらそれ以前にC#は静的クラスは継承禁止で、当然virtualには出来ない。
しかしそもそも静的クラスが継承出来ないのが問題だ。
何故これを禁止しなければならないのかは分からない。

結局>>378の「static縛り」或いは上記「staticクラスは継承出来ない」のが問題。
とはいえこの仕様では「拡張メソッド」がイマイチなのはC#開発側も認識出来るだろうから、
何らかの理由があってこの仕様なのだとは思うが。

したがって>>364の指摘どおり、
> >>329で多態が必要なのに>>352は拡張メソッドでいいというのは矛盾してるよ。
これは間違いだった。拡張メソッドが多態出来ないのは知らなかったから。

となると>>352
・Shapeクラスにメソッド追加---(α)
・GUI側でShapeクラスを継承したクラスを作って対応---(β)
>>384方式で is XXXX 形式で全部書く---(γ)
のどれかになるが、俺ならαかβであって、γはないね。

411 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:08:01.32 ID:acJIbkh4.net]
スクリプトコーダーらしいパフォーマンス無視の考え嫌いじゃないよ

412 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:18:04.05 ID:+mkoP4gZ.net]
釣りか?
仮想関数とif/switch分岐でのコストはC++の連中が死ぬほど議論しているが、
結論はどっちもほぼ同じだよ。
だからαもβもγも動作速度は大して変わらないはずだけど。
しかしそもそもC#ってパフォーマンス重視出来る言語じゃないよね。

413 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:21:51.48 ID:acJIbkh4.net]
>>396
そこじゃない

414 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:24:49.86 ID:+mkoP4gZ.net]
じゃあどこだよ?
てかチャットじゃねーんだから意見があるのなら分かるように書けよ

415 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:26:20.15 ID:acJIbkh4.net]
>>398
それ君が言うんだ?

416 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:32:20.35 ID:1sBWhH04.net]
>>396
>C#ってパフォーマンス重視出来る言語じゃないよね
これ免罪符に糞コード生み出す奴多いから困る

417 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 10:34:33.21 ID:acJIbkh4.net]
入門書も読まないスクリプトコーダーはdynamicでも使ってろってこった

418 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 11:04:12.58 ID:h1JFz9az.net]
ウザイから質問者と回答者以外が3行以上書いたら死刑な

419 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 12:58:05.84 ID:0rJ/vUpY.net]
ひょっとして結局拡張メソッドからは型の外のスコープからアクセスできるメンバーにしか
アクセスできない、っていう糞当たり前の話を延々やってだけなの?

そんなのちょっと我慢して拡張メソッドの解説記事を5分も読んだら猿でも分かる話だろw



420 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 13:59:05.59 ID:ZfPDxmLp.net]
フロントエンドコーダーってろくな人材いないよな

421 名前:デフォルトの名無しさん mailto:sage [2016/08/28(日) 14:35:00.94 ID:hQF+q+Zk.net]
>>394
実行時に解決するのは非常にコストが高い。
多分仮想関数を理解してないんだと思うけど、静的メソッドはC++やC#の方式だと仮想関数テーブルに無いので仮想関数になり得ない
また、呼び出しに失敗する可能性があるというリスクがあり、静的型付け言語の良さを殺している

>そもそもC#ってパフォーマンス重視出来る言語じゃないよね。
大きな勘違い。Roslynとかではパフォーマンスをかなり重視してる。
実行時はネイティブコードになるので書き方によってはC++と同等の速度が出る。
(ただし、C++は危険な操作を行ったりできるのでその分有利)

>staticクラスは継承出来ない
なぜなら、staticクラスは「インスタンス化、継承できない」という指定付きのクラスだから。なぜintは数値しか表せないのかみたいな意味不明な主張

>・Shapeクラスにメソッド追加---(α)
Shapeクラスが汎用的に使ったり、ライブラリとして公開するクラスならどうしようもない
WPF、WinForms、Xamarinなど、プラットフォームによって描画方法は全然異なるのでDrawメソッドを決められない

>・GUI側でShapeクラスを継承したクラスを作って対応---(β)
手間が掛かり過ぎるし、構造体やsealedクラスなら継承はできない。
クラス内にフィールドで保持してもいいが、Int32WrapperとかStringWrapper、加えて列挙体や関数、タプルなんかのラッパークラスができて複雑に。
状況によってはInt32WrapperWrapperみたいなものも爆誕






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<279KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef