ふらっと C#,C♯,C#(初心者用) Part142
■ このスレッドは過去ログ倉庫に格納されています
!extend:checked:vvvvv:1000:512 次スレを立てる時は↑を2行冒頭に書くこと(1行分は消えて表示されない為) 「どんなにくだらないC#プログラミングやVisual C#の使い方に関する質問でも誰かが優しくレスをしてくれるスレッド」です。 他のスレッドでは書き込めないような低レベルな質問、 質問者自身なんだか意味がよく分からない質問、 ググろうにもキーワードが分からないなど、勇気をもって書き込んでください。 内容に応じて他スレ・他板へ行くことを勧められることがあります。ご了承下さい。 なお、テンプレが読めない回答者、議論をしたいだけの人は邪魔なので後述のC#相談室に移動して下さい。 C#に関係の無い話題や荒らしの相手や罵倒レスはやめてください >>980 を踏んだ人は新スレを建てて下さい。 >>980 が無理な場合、話し合って新スレを建てる人を決めて下さい。 ■関連スレ C#, C♯, C#相談室 Part93 http://mevius.5ch.net/test/read.cgi/tech/1492818720/ ■前スレ ふらっと C#,C♯,C#(初心者用) Part141 http://mevius.5ch.net/test/read.cgi/tech/1544839627/ ■コードを貼る場合は↓を使いましょう。 http://ideone.com/ https://dotnetfiddle.net/ ■情報源 https://docs.microsoft.com/ja-jp/dotnet/standard/class-libraries https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/index https://docs.microsoft.com/en-us/dotnet/standard/class-libraries http://referencesource.microsoft.com/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured さすがに自前で生成してない(解放しなくていい)オブジェクトはわざわざ解放しないよ んーと、デストラクタを書かないといけないような処理があるならDispose(false)だけ書く、んだけど なにか間違ったこと言ったかな >>590 > コーダーが悪意を持ってると判断する) お前の判断なんてどうでもいい MSはそんな判断してないからデストラクタからDispose呼んでるんだろうし 書く必要がないデストラクタなら書かずに済ませるというのは同意 というか普段アンマネージドリソースなんて滅多にさわらないし まともにデストラクタを書いたのはいったい何年前だろう どうしてもデストラクタ使うなら解放忘れを解放するんじゃなくて デバッグ中に解放忘れてるぞコラということを伝える仕組みを作るほうがまともじゃないかな? 自分の考えは>>584 がほぼすべて >>566 ファクトリーメソッドを作って その中でInitすれば良かろう 解放忘れを本気で潰そうと思ったらさっき書いたようにファクトリーアイソレーションパターンを使う Task ExecuteAsync(Func<ISomeResource, Task> job) { using (var resource = new SomeResource()) { await resource.OpenAsync(); await job?.Invoke(resource); await resource.CloseAsync(); } } サービス利用者には生成も解放もインターフェースを提供しない ExecuteAsyncを通さないとリソースにアクセスできないようにすれば解放忘れを完全に予防できる >>591 フールプルーフ(ばかちょん)は何をやっても致命的にならない、 というニュアンスの方が強い。 この場合はどっちでもいいと思うけどね >>603 ばかちょんじゃなくてバカヨケだぞ 適当なこと書くなよ >>604 それは直訳で、日本語では昔からばかちょんと言うんだよ 昔からというか昔はかもしれん。 俺もおじいさん先生からしか聞いたことない言葉だし まあポリコレの時代だしね バカヨケ 失敗しないような仕組み バカチョン 誰でも使える >>592 コンテナdisposeしたら、ついでに中身も自動でやってほしいよな・・・ 横からすまんがさあ DIにMicrosoft.Extensions.DependencyInjection使ってるんだけど、これってコンテナから生成されたオブジェクトって永遠と生き続けるの? どうやって開放するん? 基本的に生成元になったスコープをDisposeするとスコープ管理下のオブジェクトがまとめて消える スコープはCreateScopeで再帰的に生成できる BuildServiceProviderで作ったプロバイダーはルートのスコープに生えてるプロバイダーと考えればいい アッドシングルトンで登録したやつは親子関係にある全てのスコープで1つしか作れずルートスコープと寿命が同期 アッドスコープドで登録したやつは各スコープ内で1つしか作れず作ったスコープと寿命が同期 アッドトランジエントで登録したやつはスコープ内で何個でも作れて作ったスコープと寿命が同期 ASP.NET Coreでは暗黙的に1つのリクエストに1つのスコープを割り当てる 訂正あったらヨロ Scope = Asp.net用みたいな気になっていて全然知らなかったよ、ありがとう ただDIなしの場合にusing句で書けるようなのはDIありでも簡単にかけそうだけど、オブジェクトを扱う箇所が数箇所に分かれてるときは難しそう・・・・ ScopeをDIコンテナに突っ込んだら突っ込んだでまた問題が増えるのかな・・・・ System.Globalization.JapaneseCalendarでeraを取得しているんだけど Rが入ってこない・・・ Windows10でWindowsUpdateも最新なんだけど、何で入ってこないんでしょう >>613 https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/japanese-era-change > To test that your application works with the new era, you must advance your computer's clock to May 1, 2019 or later. PCの時刻設定を2019/05/01以降にする必要があるらしい まずまだアップデートはオプション段階だが、KB4493443入れてる? 正式なWindowsアップデートは5月以降だよ もう元号とかやめて欲しいよねほんとw いい加減役所も西暦に一本化しろよ >>616 訂正ありがと 手元にあるのが8.1で全部おんなじかと 皆さんレスどうもです まだ対応待ちってことですね・・・ とりあえずいまはテスト用にレジストリいじれるしかなさそうですね インデクサーってpublic T this[int I]{}みたいに定義するらしいけどさあ ここに出てくるthisの部分って、this以外も入りうる余地ってあるの? >>621 無いよ this以外にするとインデックス付きプロパティって意味になると思うけど、c#には無い >>621 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/classes#indexers > indexer_declarator > : type 'this' '[' formal_parameter_list ']' > | type interface_type '.' 'this' '[' formal_parameter_list ']' > ; 入るのはthisだけで、this以外が入る余地はない ありがとう 無いものについてパッとわかるとか驚くぜ そういうのはQiitaでやれ(Qiita警察激怒) メモ系ツールなんて山ほどあるのにわざわざこんなところに書くのか 俺こんなの調べてんだぜすごいだろ?みたいな承認欲求なのかね? 初心者ですが、乱数系列の初期化(Randomクラスのオブジェクトの生成)は どこに書くのが正解なんでしょうか? 関数の中に書くと、関数が呼び出されるたびに初期化されるんじゃ?と思えるのでちょっと拙い 関数の外側にプログラムの初めの辺に書いておけばいいのかなあ?とも思うのですが、それもカッコ悪い 依存性 注入で検索したらいろいろ出てきたので調べてみます >>628 最近のは年月日時分秒を整数にして種にしてるっぽいから、 毎回初期化の方がランダム性が高まるんじゃないかと思ってる。 >>628 仕様次第 乱数の仕様を設計書に明記する必要がある >>628 訳分からん解答が続いてるけど、素直に インスタンス固有である必要があるならコンストラクタに staticでよいなら静的コンストラクタに 書けばいいだけ。かっこ悪いとか、くだらないことに悩むのは時間の無駄。 この場合は不要だと思うけど、静的コンストラクタが実行されるのはそのクラスの 静的メンバーに初めてアクセスされたタイミングだと思ったので、その点は場合によっては注意 >>633 嘘を教えるな そんな馬鹿な使い方をしたらテストできなくなるだろ private staticなら単体テストには支障ないだろ 厳密な再現性を求めるなら本来はシードを固定するべきだが >>633 そもそも因果関係が逆だよな キモメンが書いたコードがダサい >>636 staticだとコンストラクタで実装を差し替えられないから単体テストの邪魔になりやすいというのは一般論としてはある Randomを差し替える必要があるケースは極めて稀だが、上で述べたように厳密な再現性が求められるケースならありえなくもない >>635 直近のN回が特定の数列の場合のテストとかしにくいだろちったあかんがえろ >>636 テストしねーのかてめー?終わっとるな >>639 横からすまんが、そのテストしにくい例ってのをコードで見せてくれんかな 学習のためにどうか頼むわ >>640 例えばガチャを作ってるとして、0-999の乱数で0-9が出たらSSRを排出する仕様なら、 0と9と10くらいを決め打ちでテストしたくなるだろ? まあそのために乱数生成器をモックしなきゃいけないような設計には再考の余地があると思うが、状況としては普通にありえるだろう だから質問者はそんなこと聞いてないって... どんだけ独りよがりの妄想展開するんだよ 現在時刻とか乱数みたいな制御しにくい値はインジェクションする これ常識な 勉強になったねきみたち >>644 カッコイイか悪いかだから って問題があってカコワルイ ってつければ質問者の望む回答 >>639 本末転倒だろう。 作るべき物の要件に合わせて乱数生成の挙動を定義して設計するのが優先すべき事項で、その実装をテストするためのコードは必要に応じて用意すればいいだろう。 教えてください。 以下のコードで、x の定義は問題ないのに y の定義だけコンパイルエラーになってしまいます。 == const Exception e = null; const bool x = e == null; // エラーなし、true が設定される。 const Type t = null; const bool y = t == null; // CS0133 y' に割り当てられた式は定数でなければなりません。 == 何が原因でこのような違いがでるのでしょうか。 また、y を定数のままエラーが出ないように修正することは可能でしょうか。 よろしくお願いいたします。 >>652 結果によってtrueやfalseになるようなんは定数と呼ばん >>652 例外はTypeで==演算子が再定義されてるからみたいなので、 const bool y = t == (object)null; 一応これで文句言われないみたい あ、なんか例外とか意味不明なこと書いてるけど突っ込まないでねw 言語仕様の「定数式」の項を見れば別に不思議はないんだけど、 他人の書いたコードでこういう式を見たら一瞬「何の意図でこんな式を書いてるんだ?」 と思っちゃうね。 >>653 レスありがとうございます。 定数のまま、というのは const を付けたまま、という意味のつもりだったのですが、 表現が不適切だったかもしれません。失礼いたしました。 >>654 ありがとうございます!うまくいきました。 ちなみにいろいろ試してみると、 string は == が定義されているもののエラーが出ないようです。 さすがに string は特別ということのようですね。 (ただ、typeof(string).IsPrimitive は false にだったりして いまいちしっくりきませんが。。。) == const string s = null; const bool z = s == null; // エラーなし、true が設定される。 == 何にせよ、問題はすっきり解消いたしました。 適切なアドバイスどうもありがとうございました。 >>657 実際に const を使いたかったわけではなく、 問題の切り分けを行った結果として >>652 のように質問させていただいたのですが、 言われてみれば確かに何がしたいのかわからない・・・。 もう少し元の問題に近いコードを提示するなら、以下のような感じです。 == const Type t = null; if (t == null) Console.WriteLine("t is null."); else Console.WriteLine("t is not null."); // 警告なし const Exception e = null; if (e == null) Console.WriteLine("e is null."); else Console.WriteLine("e is not null."); // CS0162 到達できないコードが検出されました == >>659 いやいやいや、俺はおたくにケチつけたわけじゃないよw const bool y = t == (object)null; こういうのはぱっと見て意図が分からないと言っただけ。 むしろ「マジックナンバー」を避けるのは良い習慣ですよ >>658 >string は == が定義されているもののエラーが出ないようです。 上にも書いたけど、その辺のモヤモヤはC#の言語仕様の「定数式」の箇所を見れば解消するよ。 VSのインストールフォルダに入ってる ひょっとして、ES6あたりの感覚で代入onlyの変数を宣言したくてconstキーワードを使おうとしてるのかなと思ってみたり readonlyなローカル変数みたいな構文ってC#にはまだないんだよね >>660 > const bool y = t == (object)null; > こういうのはぱっと見て意図が分からない そうですねw 式の意味を考えるなら t == (object)null は ReferenceEquals(t, null) と書くのがわかりやすいんでしょうけど const うんぬんの話の中でこれはダメですし。 ちなみに今ふと思いついて試してみたんですが、 t is null も == の定義には依存しないものの定数扱いにはならないようです。 >>661 ありがとうございます。 言われてみると、そもそも C# と CLR の役割自体が正確に区別できていないような 気がしてきたので、これを機会に勉強してみようと思います。 >>662 質問させていただいたのは、 >>659 のコードみたいに CS0162 の警告が出てほしいのに 出てくれない場面があったからです。 でもたしかに readonly なローカル変数はあってもいいですよね。 あと、引数のみに依存して副作用もないメソッドについて ↓みたいな書き方が許されたらいいのに〜とか妄想しましたw == static class MathEx { public const double Square(double x) => x * x; } static class MyConstants { public const double SquarePI = MathEx.(Math.PI); } == 何度もすみません。。。上の妄想コードは間違いです。 正しくはこちら。 == static class MathEx { public const double Square(double x) => x * x; } static class MyConstants { public const double SquarePI = MathEx.Square(Math.PI); } == 実質的に定数ならJITコンパイル時に定数に置き換わるからそんなものは要らん List.Addって、複数のスレッドから同時に呼び出したらデータが壊れる可能性ってあるの? >>670 スレッドセーフじゃないからlock制御を自前で持つか、System.Collections.Concurrentのコレクション使うべき Queueの出し入れもlock必要だし、マルチスレッドはめんどいよな。 なんでConcurrentDictionaryはあるのにListは無いのか 個人的にはスレッド自体に特定のスレッドからのデータを受け取る処理がある方が好き 別々のスレッドから生成された値を集めたいなら、 各スレッドで別のバッファ(List)に値を書き込んでから最後に単一スレッドでマージするのが定番 スレッドセーフって実はどういう動作するのかよく知らないぜ >>676 わかる エラーがでなかったらそれがスレッドセーフ!! APIのマニュアルにおいて「スレッドセーフ」という言葉が用いられる場合、たいていは「複数のスレッドからアクセスされても例外を出さない、プログラムがクラッシュしない」というような意味です。 しかしプログラムの目的によっては、例外が出ないだけでは不適切です。 例えば対象が、100個のデータを管理する変数だとします。 その100個のデータに対して、1つ目から順に処理するスレッドと、50個目から変更するスレッドが同時に動いたらどうなるでしょうか? 結果は不定です。 この例では、排他処理 (C#なら lock ステートメントなど) と呼ばれる処置が必要になります。 ってググって出たサイトで拾った つまり for(int i=0;i<lst.count;i++) { unk un=lst[i]; 略 } みたいなプログラムを組んだとき どっかでいきなり要素をゼロにされて死ぬってことは スレッドセーフだろうがどうだろうが可能性はあるってことだよね ってことを考えるとスレッドセーフである意味ってあんまりなくて 排他処理は絶対実装しないと駄目だよね?ってこと? 誰か違うと言ってくれ スレッドセーフはメソッド内などで一貫性を保てる作り 排他制御が必要な場面でやってないなど作り手のロジックミスには対応出来るわけがない スレッドセーフである意味 あるオブジェクトがプロパティAを持っててメソッド内で b=aaa(A)+bbb(A); を計算しようとしても複数のスレッドからアクセスされることを考慮されていなければ 最初のAと次のAが違う場合があり計算結果が期待したものにならないかもしれない スレッドセーフはこういう場合でもちゃんと計算される仕組みを持つ >>679 その処理は要素数チェックと要素アクセスが分かれているから、間に他スレッドからの処理が割り込み得る System.Collections.Concurrent系のコレクションは、 例えば「要素があるなら取得」のようなまとまった処理がatomicになっているので、他スレッドからの割り込まれない(=スレッドセーフ) どっかのスレッドで詰めて、別のスレッドでループ処理、がやりたいのならBlockingCollectionが楽 >>679 厳密に他のスレッドとの同期を取らなきゃいけないなら>>682 の言うようにBlockingCollection使うか毎回ロックだろうし、 ループ中は他のスレッドによるlstの変更を反映しなくていいならループに入る直前だけロックしてコピーしておけば済む ケースバイケースだよ 一つ一般的なアドバイスをしておくと、並列処理のコツはデリケートな前提をなるべく設けずに極力ロバストな設計をすることだ 要件が許す限りにおいて、少々処理の順番が入れ替わったり処理間の同期が取れてなかったりしても問題にならないつくりにするのが理想 非同期処理は複数のスレッドが同じデータを弄ろうとすることによる不整合は起きないけど コールスタックは複数になるから 同じデータに触ると訳ワカメになる事があった (||゚Д゚)ヒィィィ!(゚Д゚||) じゃあ>>679 みてーな処理を書いたら スレッドセーフなんて関係なく バグるんだね こぇえええええ じゃなくて終わったわ 今まで組んだもんでテキトーにやった箇所全部終わってる気がする まあ複数スレッドで同時並行処理するときにはそのへん慎重を期さないと 再現困難なバグを埋め込んじゃうからねえ 同時に読み書きする可能性のある変数を安易に書き換え/差し替えしちゃダメ マルチスレッドの恐ろしさは、たまにしかバグらない事。 ほとんどは正常に動くから、質が悪い。 必ず、バグらないだろ それで喧嘩になる事も多い。 マルチスレッドは、ベテランでもバグるからやめろと言っても、 ほら、バグらないでしょ? と、突っかかってくる その時には、バグらないと言うと、 千回実行しても、バグらないでしょ? と、突っかかってくる。 でも、その時にはバグらない バグる立証をするのが難しい だから、Ruby をやった人は、関数型言語のElixir をやる。 他の言語の人は、何を言っても、そのテスト回数でバグらないと言ってくるから、質が悪い 1万回実行しても、10万回実行しても、その時にはバグらないものなんだよ。 何回バグらないで実行すれば、正しいと認めるのか、と問われても困る >>687 喧嘩になるのはマルチスレッドのバグのせいではなくお前の頭がバグってるから >>687 マルチスレッドはバグるからやめろってなるのでなく、バグが無いように作れよ。 あと、お前の意見を相手が聞き入れず喧嘩になるのは、お前がいつもバカなことを言うから相手は当然受け入れる気にならず、お前にはその自覚がなくて「何でアイツは僕の言うことを理解してかれないんだウワアーーー」ってなってるからだぞ。 >>687 なんでバグが起こってるのか原因特定出来てなくてワロタ スレッドセーフは単発のメソッドが競合しないだけで 一連の処理についての動作保証をするものではないと マルチスレッドはやらなくていいならそれに越したことはないけど 絶対に駄目というわけではなく 排他処理を組まないことが害悪 排他制御をしなくても安全に並列処理できるように設計することが大事 まずはロック、クリティカルセクション、ミューテックス、セマフォ、といった待ち時間を発生させるタイプの機能を使ったら負け、というルールで設計に挑戦してみるといい 大半の並列処理でそんなものは必要ないこと、それらを使わないほうが圧倒的に設計とプログラムが綺麗になることを体験するべき ぱられるふぉーってのを使えば良いんじゃね? 知らんけど ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる