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


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

C#, C♯, C#相談室 Part88



1 名前:デフォルトの名無しさん mailto:sage [2015/07/25(土) 16:14:05.15 ID:I42JqLkf.net]
■Visual Studio 2013 Community & Express(無償の統合開発環境)等はこちら
www.visualstudio.com/downloads/

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

■前スレ
C#, C♯, C#相談室 Part87 [転載禁止](c)2ch.net
peace.2ch.net/test/read.cgi/tech/1427558696/

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

620 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 18:44:40.15 ID:JbH8lT1Q.net]
MSDN確認してその通りにやればいいだけでは?

> 基本クラスが IDisposable を実装する場合は、オブジェクトは基本クラスの Dispose メソッドも呼び出す必要があります。
> Dispose のメソッドを明示的に呼び出す必要があるため Dispose のメソッドを呼び出してオブジェクトのコンシューマーがに失敗したため、
> アンマネージ リソースが解放されないこと危険性が常にあります。 これを回避するには、次の 2 とおりの方法があります。
> ・System.Runtime.InteropServices.SafeHandle から派生されるオブジェクトのマネージ リソースをラップしてください。
> ・Dispose が呼び出されないときにリソースを解放するようにファイナライザーを実装してください。
> StreamWriter などのアンマネージ リソースにアクセスするオブジェクトを使用するときは、using ステートメントでインスタンスを作成することをお勧めします。
> using ステートメントは、使用しているコードが完了すると、ストリームを自動的に閉じ、オブジェクトの Dispose を呼び出します。
> https://msdn.microsoft.com/ja-jp/library/system.idisposable.dispose(v=vs.110).aspx

621 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 18:50:22.66 ID:53h6zSH3.net]
CLR再起動

622 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 18:50:45.39 ID:hc4Y2Ev5.net]
>>604
それでは共同作業になりませんね、そこまで自我を通したいなら自分一人で作業するしかないでしょう
取り決めは大事

623 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 18:53:42.93 ID:MIhiF6BJ.net]
>>613
共同作業を円滑にするために、常にDispose必須、とかいうオレオレルールを排除しなければならない
理由はもう説明したな

624 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 18:59:05.24 ID:53h6zSH3.net]
今度は共同作業のマナー論ですか
君らはまず場を弁えることを学ぶのが先決では…

625 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:02:58.05 ID:8rh7GHk2.net]
>>592
Font, Brush, Penなんかは自分で作った物(システムリソースじゃない)であっても
今のWindowsではいちいちDisposeしなくてもまず何の問題もない。

そうは言っても習慣で書いちゃうけどね。

626 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:09:30.05 ID:2AMvri3n.net]
>>616
そうなんだ

でも呼ばないと高コストなファイナライザでの解放になっちゃうしね

627 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:24:52.17 ID:qzhEyH2V.net]
今unityでゲームを作っているのですが、累計の記録ってどう書けばいいのでしょうか?
今まで対象のオブジェクトが何回タップされたか記録したいです。
playerprefsを使えばできますか?

628 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:25:54.56 ID:idej2sB9.net]
unityスレで質問しなよ



629 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:36:46.47 ID:hc4Y2Ev5.net]
Disposeがどうしても嫌なら、勝手に俺ルールを作り出さず素直にファイナライザに書けばいいんだよ
そういうルールで作ろうという事になっているんだから
それで問題なければそれで上手くいく、そうでないものは決められた極力ルールに従う事

そうしてファイナライザのみにすると具合が悪い話が必ず出てくると気付くはず
例えば、ファイルオブジェクトのように、ロック握っている奴とか
例えば、アンマネージ側の参照カウンタがカウントダウンされなくて予想外のメモリーリークしたとか
例えば、C++のつもりでデストラクトの順序を考えていたら予定外の順序でファイナライザが起動してクラッシュしたとか

630 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:44:15.23 ID:0gT6iToJ.net]
>>616
システムリソースじゃないってほんとかい? GDIオブジェクトとしてタスクマネージャに表示されるんじゃないの?
でも大概描画=なんども呼ばれるシナリオだから
そのたびに破棄しておいたほうがメモリ的にも安心じゃね?

631 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:45:43.68 ID:MIhiF6BJ.net]
>>620
何回言えばいいのかな
呼び出しが必要な必要と使用に明記する
明記されない以上は明記しなくても問題ないように実装する
それが社会のルールだ
呼ばないとダメになる場合があるのにそれを仕様に明記しないでDisposeが呼ばれるオレオレルール(出典不明)を前提に作るな
クズが死ね

632 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:53:17.04 ID:JbH8lT1Q.net]
>>616
今更ながらPenがDisposeを実装していると知った。(もちろんDisposeしたことはない)
何でこれまで気づかなかったのかと探せば、
PenのサンプルコードではDisposeしているが、DrawLinesのではしていないからだ。
> https://msdn.microsoft.com/ja-jp/library/system.drawing.pen.dispose(v=vs.110).aspx
> https://msdn.microsoft.com/ja-jp/library/7ewkcdb3(v=vs.110).aspx
なお、これまで特に問題を感じたことはなかった。

>>617
Finalize自体はDisposeと大して変わらないよね?
GC自体のコストと、メモリ撹拌の問題はあるにしても。
Disposeした方がもちろんお行儀がいいとして。

てか、gcnew って delete しなくていいためのものじゃなかったんかー!
ファイルはクローズしてるけど、他は全部放置してたわw
(なおVC++使い)

633 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 19:58:35.53 ID:nxY8tWuM.net]
このスレを読んだら初心者の私もウルトラスーパーハイパーミラクルアルティメットDispose名人になれました!

634 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:01:04.88 ID:MIhiF6BJ.net]
>>623
deleteしなくても良いであってるよ
自動化したのに手作業が必要なんて馬鹿みたいだろ

635 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:08:50.19 ID:9aqT3FI6.net]
でも、ファイナライザは論理アドレスが圧迫されてGCが発動しないと呼ばれないよ
メモリとシステムリソースは別物だから、
開放のトリガーを論理アドレスの枯渇に頼るのは良くない作法なのでは

636 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:09:16.04 ID:hc4Y2Ev5.net]
初心者の頃 Disposeし忘れて、ライブラリの書き直しが大変な事になったのでは GetEnumerator() で取ってきたIEnumerableのDisposeのし忘れかな
ファイルオブシェクトをこっそり握っていて、ファイルがロックされたままだったのを
色々システムを結合した後に気づいて、泣きそうになった
C++から移行した後、嵌ったのは
class A
{
 ~A() {}
}
class B
{
 A a;
 ~B() {}
}

var tmp = new B();
こういったケースかな、C++であれば必ず a のデストラクタが後だが C# だとどちらが先になるか分からなくなる
C++と違いデストラクタではメンバは迂闊に触れないという事実を思い知らされた

637 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:18:42.77 ID:hc4Y2Ev5.net]
おっと、GetEnumerator() で取って来れるのは IEnumerable ではなくて IEnumerator でした
Disposeがリソースと関係なく必要になるケースはC++と違いデストラクタがまともに使えないという事情から来ることも多々あります

638 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:20:23.58 ID:ZkLCFLWu.net]
まだやってやがる
死ねよマジで
それともあれか、手伝って欲しいのか?
殺してやるから住所教えろや



639 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:26:42.76 ID:0gT6iToJ.net]
>>629
おまえの住所先に書けやバカヤロウ

640 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:27:29.87 ID:bbkyb+Wi.net]
見なかったことにしてやるからさっさと執行してくれや

641 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:31:02.28 ID:MIhiF6BJ.net]
おうかかってこいやチキン野郎

642 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:50:07.75 ID:JbH8lT1Q.net]
>>625
コンセプトとしてはその通りだけど、ID:hc4Y2Ev5が言っているのもまた然りだと思うよ。

本来は、全部GCに任せた上で、理由がある場合のみ手動でDisposeという仕様を目指しているのだと思う。
現実的にはこれはほぼ完成しており、通常の範囲で問題になることはない。(少なくとも俺は命中していない)
ただ、MSDNで
> 基本クラスが IDisposable を実装する場合は、オブジェクトは基本クラスの Dispose メソッドも呼び出す必要があります。(611)
と言っている以上、Finalizerだけでは駄目なケースがあって、それに命中する可能性も残っているのだと思う。
とはいえ、普通に実装すればFinalizeはまずDisposeをコールするだろうから、
問題が発生

643 名前:キるとしたらタイミングだけのはずだけど。

確認してみたけど、C#のデストラクタは起動を予約してGCから起動するという仕様のように見える。
> http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_011/csharp_abc03.html
確かにこれだとFile等はClose/Disposeをしないといつロックを解除してくれるか分からない。
だから>>627-628の言うことはあっている。620の3つのケースもあり得ると思う。
理由は指摘の通り、C#ではデストラクタの起動順/タイミングが規定できないからだね。
[]
[ここ壊れてます]

644 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 20:50:20.22 ID:1KB/gLgO.net]
>>584
特定の方法でインスタンス作った時にだけ意味があるというのは割りとある
例えば、FormをShowした時とかは自動でDisposeされるから不要

645 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 21:31:38.21 ID:hc4Y2Ev5.net]
>確かにこれだとFile等はClose/Disposeをしないといつロックを解除してくれるか分からない。
ファイルオブジェクト的な物を使う側ではなく作る側で、実際にいろいろやってみて面倒な事になってるなと思ったのは
フィールド上に確保していたバッファがデストラクタ中のクローズ処理よりも先に解放されてしまうなどですかね
アンマネージの場合はこの辺は実にすっきり記述できるんですが、マネージでは厄介です

初心者の時
~Class() { Dispose(); }
なんて事をあまり深く考えずにやってました、そして謎の異常終了を発生させてましたね
Disposeが呼び出されずにデストラクタが呼び出されたら、できることはもはや安全停止だけです
まともな終了処理は最早できません

646 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 21:35:34.12 ID:OpHxID+X.net]
C++のノリでデストラクターを間違った使い方して
GCの洗礼を受けたのはわかった

647 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 21:37:58.50 ID:aJXfAZiV.net]
もうskypeで議論して最終的に友情をめばえさせたら?
C#である必要もないし

648 名前: ◆QZaw55cn4c mailto:sage [2015/08/23(日) 21:38:38.49 ID:GHcBJPT0.net]
C++ でも delete this は普通やらない‥



649 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 21:40:51.66 ID:hc4Y2Ev5.net]
デストラクタ的な機能が欲しければC#ではDisposeしか手段が無いんです
ファイナライザは使えません、その処理はシステムに任せることはできないのです
それが分かっていないと安易にDispose不要という考えが出てしまいます

650 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:03:58.87 ID:pgaNpm//.net]
はいはいちごいねー

死ね

651 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:09:13.04 ID:oScCmTRi.net]
おい待てよ
Dispose不要派は
1.ファイナライザーでやればいいんだぜ
だけじゃなくて
2.解放など軟弱もののやること だってボクの環境で問題になったことないんだもん
の方が多数派だろ

652 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:11:48.27 ID:rrCWAeC5.net]
>>641
うるせえ喋んなカス死ね

653 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:13:14.66 ID:nxY8tWuM.net]
ここまで全部俺の自演

654 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:16:59.42 ID:1KB/gLgO.net]
>>633
IDisposableを実装している場合は、明らかに不要な場合以外は使い終わった後にすぐDisposeすべき
PenもBrushも中にGDIのハンドルを抱えてるわけで、アンマネージドのシステムリソースやメモリを必要以上に使ってしまう
ファイナライザは残っていると仕様上開放が先延ばしになって長時間メモリを占拠するから、想定よりコストは高い

>てか、gcnew って delete しなくていいためのものじゃなかったんかー!
WindowsがすべてGCの管理上で動くようになればな。GC管理外のデータはプログラマが責任を持たざるをえない

655 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:21:09.75 ID:hc4Y2Ev5.net]
コストに関しては、昨今はシビアなノーパソでもない限りは自分はあんまり気にしなくなってたりしますw
ロジック的にDisposeが必要不可欠な物の方を意識したいところです

656 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:24:17.01 ID:prCrabVF.net]
そういやVS2015から、IDisposable選択して右クリック→クイックアクションで、
Disposeのひな形吐き出してくれるんだよな。便利になったものだわ

657 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:29:32.06 ID:MIhiF6BJ.net]
最初から何度も言ってるがこれが正解な

1. Disposeしないと機能的にアウト→Disposeする
2. 機能的に問題ないがボトルネックになる→Disposeを許す
3. 機能的に問題ないうえに負荷も軽微→自動化しろ手で書くな

クライアントは殆どが3なんだわ
Disposeなんか要らないんだよ
これが今日のまとめね

658 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:33:20.72 ID:hc4Y2Ev5.net]
3. 機能的に問題ないうえに負荷も軽微→元クラスのIDisposeを除去せよ
これが正解です



659 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:37:13.05 ID:YS/VElDC.net]
1日かけて成果物3行って舐めてるのか貴様ら

660 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:37:24.13 ID:JbH8lT1Q.net]
>>639
仰るとおり、C++→C#へのポーティングではC#のデストラクタには期待できないから、
いちいち手動で順番も考慮してDispose()しかなさそうだ。
ただこれはだいぶ手間だから、何らかの上手い解決策が既にありそうだけどね。

仕様から言って、C#ではデストラクタの起動順を期待するコーディングをしてはいけない。
ただ、
> フィールド上に確保していたバッファがデストラクタ中のクローズ処理よりも先に解放されてしまうなどですかね (635)
これはよく分からない。(これが発生する可能性がシステム的にあることは分かる)
とはいえ、C#って多重継承できないし、アンマネージドとマネージドを混ぜてぐちゃぐちゃにしたりすることがなければ、
これって無いよね?
(逆に言えば、マネージドコードだけならこういったことは発生しない、と思っている。
そして本来はアンマネージドを大量に使うことこそが問題。ポーティングならある程度致し方ないにしても。)

661 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:37:59.91 ID:hc4Y2Ev5.net]
ここにはゲーム等、ハイパフォーマンスが必要になる人もいるでしょう
その時Disposeしなくても問題ないと開発元に確認できた、Disposeしない方が高速である事が確認された
そして、それをする事でソフトの商品価値が向上する、この条件でDisposeしないを選択するのが正しいと思う
それ以外は必ずやらなければ駄目です

662 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:38:00.89 ID:HkRU0Alf.net]
機能的に問題ないがDispose使わないとボトルネックになるなんて
どんな状況だよ

663 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:38:38.88 ID:MIhiF6BJ.net]
>>649
行数にこだわるのは老害の証
現代のプログラマは中身を見ないと

664 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:39:55.83 ID:+kgkAxfw.net]
>>647-648
「だから何」レベルのまとめはQiitaにでも書いといて
あと死ね

665 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:41:15.09 ID:prCrabVF.net]
なんかしらんが、このレベルの話題が一番盛り上がるよな
上でも下でもこうはならん

666 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:42:20.89 ID:bbkyb+Wi.net]
毛の壁を笑えんよこれは

667 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:45:56.71 ID:hc4Y2Ev5.net]
>>650
マークスイープでは順序を決めることができないんですよ
循環した参照がある場合どこから削除すべきかという判断材料がなくなる、ならば最初から順番は無視という判断なのだと思います
実際ガベコレ毎に順序は出鱈目です、気を付けてください
C++の場合、例えば循環参照があったらメモリーリークですが、プログラマのレベル高いから平気だよねってコンセプトではない訳です

それにしてもC++の芋ずる式デストラクタは気持ちいいです・・・

668 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:53:59.24 ID:MIhiF6BJ.net]
>>650
マネージドだけでも普通に発生する
バッファが回収可能になるのと所有者インスタンスがFRQにぶち込まれるタイミングはほぼ同時
どっちが先に処理されるかは誰にもわからない



669 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:58:36.70 ID:MIhiF6BJ.net]
というのは嘘だ

670 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 22:59:24.15 ID:rRq+bYgY.net]
>>659
そうかい
では死ね

671 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:01:02.88 ID:MIhiF6BJ.net]
>>660
しゃぶれよ

672 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:02:56.73 ID:5fcokCbE.net]
バカには難しかったかな
クラスAのオブジェクトaはクラスBのオブジェクトbを参照しているとする
A a = new A();
a = null;
ここでaとbが同時に解放対象になって、aとbの解放順序が非決定的

673 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:04:45.05 ID:9aqT3FI6.net]
何でそんなサンプルコードが必要だと思ったの?

674 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:06:20.29 ID:JbH8lT1Q.net]
>>657
見た目はマークスイープだけど、中身は参照カウント方式だったはず。(だからそれなりに順を追ってGCされる)
というのを中の人が書いたドキュメントがあったはずだが、検索しても今はでてこない。
ブクマによると多分以下なのだが、アーカイブになっていてどれなのか分かりませんorz

Microsoft .NET Framework の自動メモリ管理 Part I
msdn.microsoft.com/ja-jp/library/bb985010.aspx

675 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:07:02.82 ID:hc4Y2Ev5.net]
C++の人は、ここをミスしやすいと思うし、見ている印象結構C++からやってきた人多そうだから
悪くないサンプルだと思うのですが・・・

676 名前:デフォルトの名無しさん mailto:sage [2015/08/23(日) 23:10:23.32 ID:MIhiF6BJ.net]
>>662
と思うじゃん?

677 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:08:47.57 ID:genYk8wg.net]
さてまとめるか。
「不必要にDisposeを量産するバカが多いため
usingを怠る悪習が蔓延した」

678 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:31:00.45 ID:e5Jihg5N.net]
IDisposeを持つオブジェクトを握るオブジェクトはIDisposeを持つしかない
不用意でなくても普通に増えるしかないよ
IDisposeを持つ物は Stream や Task があるがどれも基本的なクラスばかりで避けては通れない



679 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:35:53.34 ID:4CFfNfbx.net]
>>662
さすがにそのケースでのリークはないよね?

Array等の中身として参照を持っているだけなら、
そもそもデストラクタがどちらから呼ばれても問題ない。

継承関係なら自動でやってくれるはず。
自作クラスで継承以外で引っ張ってきている場合、必要ならデストラクタにその順通り書けばよく、
デストラクタがいつ呼ばれるかは問題ではない。
(自作クラスの一つのデストラクタだけで済むように構成する。
ただしリソース解放が必要ならDisposeを実装しないとタイミングが読めない。)

菱形継承で先に基底クラスが解放されたりするのは問題になるけど、C#にこれはない。

だから問題になるのは、一度しか呼ばれないアンマネージド側で
マネージドのデストラクタが呼び出し済みなのを期待している時で、多分これだけだよね?
マネージド側は放置しててもなんだかんだでいつかはGCされるはず。
それが嫌ならDisposeしろって事で。
だから、アンマネージドを先に全部解放するようにすれば、問題は発生しないと見た。

680 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:36:24.75 ID:4CFfNfbx.net]
なお、MSDNのデストラクターにまんま書いてある。
> デストラクターがいつ呼び出されるかはガベージ コレクターによって決定されるため、プログラマは制御できません。
> 一般に C# では、ガベージ コレクションを使用しない言語で開発する場合ほど、メモリ管理を必要としません。
> .NET Framework のガベージ コレクターが、オブジェクトに対するメモリの割り当てと解放を暗黙的に管理します。
> ただし、ウィンドウ、ファイル、ネットワーク接続などのアンマネージ リソースをアプリケーションでカプセル化するときは、
> デストラクターを使ってこれらのリソースを解放する必要があります。
> アプリケーションで貴重な外部リソースを使用している場合は、
> ガベージ コレクターがオブジェクトを解放する前にリソースを明示的に解放する手段を用意することをお勧めします。
> この処理を行うには、オブジェクトに対して必要なクリーンアップを実行する Dispose メソッドを IDisposable インターフェイスから実装します。
> これによって、アプリケーションのパフォーマンスを大幅に向上させることができます。
> このようにリソースを明示的に制御する場合でも、
> デストラクターは、Dispose メソッドの呼び出しが失敗したときにリソースをクリーンアップするための安全装置になります。
> https://msdn.microsoft.com/ja-jp/library/66x5fx1b.aspx

681 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:42:37.88 ID:e5Jihg5N.net]
C#の場合デストラクタでやっていいことは、static関数の呼び出しくらいだろうな
class型フィールドの内容に触ることはできない、触ってよいのは int や enum といった値のフィールドだけ
それ以外の操作をしたければDisposeを使うしかない
順序良く呼び出されたとしてもこれでは何もできない

682 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 00:51:10.64 ID:OjRQ25eS.net]
ID:4CFfNfbx
この人は何言ってるかわからなくて、頭くらくらしますよね
そもそも話が通じてないし

683 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 01:04:15.56 ID:e5Jihg5N.net]
C++からのポーティングが引き返せないところまで来ているのかもw
笑っちゃいけないか、ご愁傷様かな(ナムナム

684 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 07:38:39.63 ID:FEQDPFGC.net]
なんか、マネージド/アンマネージドコードとマネージド/アンマネージドリソースがごっちゃになってる人がいるように見えるのは気のせいだろうか。

685 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 07:41:36.51 ID:xNseMvgF.net]
蒸し返すなゴミクズ

686 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 09:19:55.49 ID:h+mHYijt.net]
まだ続けるの?

687 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 09:50:06.14 ID:xNseMvgF.net]
もうウンザリ

688 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 10:58:39.56 ID:/7MwCGkP.net]
嫌なら見るな



689 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 11:48:38.94 ID:Q0ZjIosN.net]
いや、低レベルな話がしたいならふらっと行けよ
だからテメエは無脳なんだ

690 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 12:27:15.22 ID:e5Jihg5N.net]
一番低レベルなヤツ -> 679

691 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 13:03:00.83 ID:kR1o4QUh.net]
ここが隔離スレだ

692 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 15:21:00.93 ID:/7MwCGkP.net]
なんでいつも単発IDなんですかね

693 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 15:48:52.90 ID:CmRZDEoS.net]
単発が嫌なら見るなよ

694 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 15:52:52.92 ID:mvfSohk+.net]
>>682
IDがきちんと出るようにするだけの技術力がないから…

695 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 20:40:58.44 ID:UIihvy++.net]
C#って内部実装変えただけでも依存するアセンブリビルドしなきゃなの?

696 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 20:45:58.83 ID:xp4qRvA3.net]
必要なし

697 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 21:02:14.07 ID:aDhIIP+g.net]
ザマリン標準化まだ時間かかりそうですか

698 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 21:25:54.27 ID:vU2SL/AS.net]
Xamarinは目先の金儲けしか頭にないから期待しても無駄



699 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 21:46:54.78 ID:8rH+FULH.net]
>自作クラスで継承以外で引っ張ってきている場合、必要ならデストラクタにその順通り書けばよく、

これ正しいの?

700 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 22:31:14.60 ID:vU2SL/AS.net]
そのファイナライザ内だけで完結するんならそりゃそうだろ


701 名前:AとBが両方ともアンマネージリソースを抱えている
・AがBを参照している
・ネイティブライブラリの仕様でBはAより先に解放しなければならないと決まっている
こういう状況では当然単純にAとBのファイナライザに頼るわけにはいかない
Bにはファイナライザを実装しないでAのファイナライザ内でBのリソースを解放し、
その後にAのリソースを解放するといった工夫が必要になる
[]
[ここ壊れてます]

702 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 23:17:12.96 ID:4CFfNfbx.net]
>>674
すまん、その通りだ。C#ではアンマネージドコードは禁止とは知らなかった。
解放しているのはunsafeで生ポインタだけか。
インラインアセンブラが出来るというのを見た覚えがあるのだが、気のせいだったようだ。
デストラクタも継承/オーバーロード禁止だから、>>671の言うとおり、staticにしか使えない。

C++からポーティングするなら、
デストラクタ内のは全部Disposeに移動し、そこで手動で親を呼んでおけばいい気がする。
これだとクラス内だけで留まる。
リソース解放タイミングを規定したいのなら手動でDisposeを呼ぶか、usingだね。
ただ、呼ばなくてもセグフォにはならないはず。

MSDNには
> C++ 経験者が C# で開発する場合
> デストラクタ : C# は、アンマネージ リソースを確定的に解放する場合の構文が異なります。
> デストラクタ
> using ステートメント (C# リファレンス)
> https://msdn.microsoft.com/ja-jp/library/yyaad03b(v=VS.90).aspx
だけだから、推奨はusingのようだ。

マネージドコードだけしか使えないのなら、本質的なリークはどうやっても発生しないように思える。
一時的なリソース枯渇はあり得るけど、例えばGDIなら描画しまくるアプリ(ゲーム等)でなければあまり気にしなくてもいいのでは。

703 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 23:21:14.35 ID:agiYVVps.net]
>リークはどうやっても発生しないように思える

こういう馬鹿がプログラミングの真似事をするとロクなことがない

704 名前:デフォルトの名無しさん mailto:sag [2015/08/24(月) 23:23:09.51 ID:163KCsEM.net]
簡潔に一度だけ言うね
ID:4CFfNfbxはあと三年ROMってから
それからカキコしようね

705 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 23:26:49.44 ID:OjRQ25eS.net]
これさー
メモリ以外のリソース、たとえばウィンドウハンドルやGDIオブジェクトetcがさー
枯渇とまでいかなくても、使いすぎと感知したタイミングでGCが発動する仕組みが.Net側にあれば、
usingとか、ファイルなんかの特殊な事例以外では、要らなくなるのでは?
GC発動のトリガーがメモリだけに依存しているから、いろいろ心配になるわけで

706 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 23:27:45.15 ID:vU2SL/AS.net]
ファイナライザ内で別のオブジェクトにアクセスするのは基本的には問題ないぞ
その別のオブジェクトがファイナライザを持ってる場合には
既にファイナライザが呼び出されて無効になっている可能性があるからダメというだけ
ファイナライザを持ってるオブジェクトから参照で辿れるオブジェクトはどのみち全部一度復活して
GCを妨害してしまうから、アクセスすることが特にGCの妨げになるということもない
一番悪いのは「ファイナライザを実装すること」自体な

707 名前:デフォルトの名無しさん mailto:sage [2015/08/24(月) 23:57:38.17 ID:e5Jihg5N.net]
ファイナライザに実装すべきなのは、安全装置だけだろう
例えばアンマネージドのハンドルを握っている場合
ハンドルはIntPtrだから、別のクラスに入れるといったことをせず直接フィールドに配置しているなら
アクセス可能だから、ここでリ参照カウンタをダウンすれば一応解放は可能
fopenみたいなものを相互運用している場合もハンドルとstatic関数をdllから呼び出せるなら
バッファのフラッシュは諦めるとしてもファイルを閉じることくらいはできる
いずれも最終手段レベルだね

708 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 00:04:34.64 ID:uHUYRmLo.net]
>>691
リーク問題については、あまり期待しないほうが良い
Excelの相互運用なんかをすると、当マイクロソフト製なのに結構厄介だし、洩れまくるし
自作でやってもなかなか糞な事になる



709 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 00:42:16.41 ID:FzRJlm7d.net]
すいません言い直します。

・C#では、正しく構成されたクラスを使用している限り、本質的なリークは発生しない。
(明示的にDisposeしなくてもいつか回収される《=Finalize時にDisposeが呼ばれる》)

じゃないかな?
もちろん.NET謹製のはリークしない。
自作クラスでアンマネージリソースを使う場合、MSDNによると、
・Disposeを実装し、SafeHandleでアンマネージリソースをラップする。←こっちがオススメ
・Finalizeを実装する。
のどちらかをやっておけばいいはず。
> https://msdn.microsoft.com/ja-jp/library/498928w2(v=vs.110).aspx

だからリークしてるのであれば、自作クラスの構成がまずいのだと思うのだが。
もちろんクラスの構成はC++流(デストラクタ)ではなくC#流(上記)にしないといけない。

710 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 00:50:30.42 ID:wg5Da8me.net]
ListAとListBの中身を1つずつ比較して、ListBの内1つがListAに無かったらそのオブジェクトを追加し
同じものがあれば追加しないと言う機能を作りたいのですが、foreachだと例外が出て、
for文だと無限ループになってしまいどうやっても上手く実装できませんでした。
一体どうすればListの中身を1つずつ比較して問題なく追加する事が出来るのか教えていただけないでしょうか

711 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 00:57:16.45 ID:bwlYR2I5.net]
問題が起こる、最小のコードをアップしなさい

712 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 01:11:01.00 ID:wg5Da8me.net]
色々書き換え続けて最終的にコンパイルすら通らなくなったんですが多分こんな感じです。
if (ListA.Count == 0) foreach (var li in ListA.a) ListB.Add(li);

else for(int i=0; i < ListB.Count; i++){
  for (int x = 0; x < ListA.Count; x++){
if (ListA.a[x] != ListB.a[i]) ListB.Add(ListA.a[x]);

}}

713 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 02:03:56.13 ID:bwlYR2I5.net]
for( a: A )
for( b: B )
{

714 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 02:07:01.06 ID:bwlYR2I5.net]
擬似コードですが、これでどうでしょう
for( a: A )
{
  bool found = false;
  for( b: B )
  {
    if( a == b ){ found = true; break; }
  }
  if( !found ){ B.push_back( a ); }
}

715 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 02:56:24.98 ID:wg5Da8me.net]
よく考えてみたら1つずつ比較してる最中、違った瞬間に追加するってコードになってました。
それで調べたら配列の中を比較するIndexofという機能をついさっき知って実装したところ、上手く動きました。

716 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 04:17:23.94 ID:ljTVrax0.net]
ListB = ListB.Union(ListA).ToList();

717 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 07:28:11.84 ID:uHUYRmLo.net]
>>698
shared_ptr weak_ptr の使い分けのように仕組みを意識して使わないと
システム任せだと無理があるんだよ、SafeHandleを使えば万事解決という訳にはいかない
そろそろ諦めなはれ、アンマネージと相互運用したければ覚悟決めるしかねーですw

718 名前:デフォルトの名無しさん [2015/08/25(火) 10:56:12.32 ID:y1FTBoUo.net]
アンマネージドとかどういう場面で使うんですか?
C言語とかの領域ですよね?
本見てもどういう場面で使うのか乗ってないんですが



719 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 11:03:08.95 ID:aUx99M6r.net]
アンセーフ?

720 名前:デフォルトの名無しさん mailto:sage [2015/08/25(火) 11:33:21.01 ID:Wpti2W5K.net]
SafeHandleってサーバーで複数のドメインが1プロセスに同居するような特殊なシステムでない限り何の意味もないんだけどな
使いたがる連中のなかでそれを正しく理解してるのは少ない






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

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

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