ふらっと C#,C♯,C#(初心者用) Part130 [無断転載禁止]©2ch.net
レス数が950を超えています。1000を超えると書き込みができなくなります。
「どんなにくだらないC#プログラミングやVisual C#の使い方に関する質問でも誰かが優しくレスをしてくれるスレッド」です。
他のスレッドでは書き込めないような低レベルな質問、
質問者自身なんだか意味がよく分からない質問、
ググろうにもキーワードが分からないなど、勇気をもって書き込んでください。
内容に応じて他スレ・他板へ行くことを勧められることがあります。ご了承下さい。
なお、テンプレが読めない回答者は邪魔なので後述のC#相談室に移動して下さい。
C#に関係の無い話題や荒らしの相手や罵倒レスはやめてください
>>980を踏んだ人は新スレを建てて下さい。
>>980が無理な場合、話し合って新スレを建てる人を決めて下さい。
■前スレ
ふらっと C#,C♯,C#(初心者用) Part129
http://mevius.2ch.net/test/read.cgi/tech/1497000961/
■関連スレ
C#, C♯, C#相談室 Part94 [無断転載禁止]©2ch.net
http://echo.2ch.net/test/read.cgi/tech/1492843013/
■コードを貼る場合は↓を使いましょう。
http://ideone.com/
https://dotnetfiddle.net/
■情報源
https://msdn.microsoft.com/en-us/library/gg145045.aspx
http://referencesource.microsoft.com/
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured オブジェクト指向はプロジェクトが大きくなるほどベストの設計は存在しないんじゃないかと思う
ベストを目指しベターを繰り返していくけど結局正解はないと思い知らされる 成果物に問題がなくて、そこそこ保守性が良ければ
無理にベストを目指す必要も無いからね
ベターをベストにする労力を掛けるより、
その労力で別の事をした方がいい >>879
そういうものだよ
だからカイゼンを繰り返せるように設計する
最悪な設計は間違った設計ではなく変更が難しい設計
現代のOOPの常識だね 変更のしやすさって開発スタイルに依存するからなあ
システムを作る側とそれを利用する側とで責任が分かれてる体制下においては、
綺麗なドメインモデルを継続的に改善し続けるなんて不可能
ひたすらコントローラでSQLを垂れ流す方が遥かに変更しやすい 長大で無数のSQLなんてメンテしたくないよ
リポジトリパターンにしておけば1時間もかからない仕様変更に何日もかかるようになる
テストの工数も考えると辟易するね >>882
コントローラーでSQL垂れ流しって時点で、UnitTest考慮ゼロだな 設計フェーズでちゃんと客と握ってれば仕様変更は客に相応のコストを請求すればいいでしょ
変更にかかる工数はトランザクションスクリプトなら高精度で簡単に見積もれる
変更しない前提ならテストなんか画面でポチポチしてExcelにスクショ貼り付けた方が早い
>>882で変更しやすいと言ったのは運用保守フェーズに入ってからの話ね 簡単に変更コスト見積れるトランザクションスクリプトのシステムなんて見たことないな
どこで何をやってるかすぐにはわからない
SQLが酷いと優しく言っても地獄 > だからカイゼンを繰り返せるように設計する
思いつきで仕様決める奴の理想。現実は一度決めた仕様を捨てることは困難。 >>887
仕様と実装の区別も付かないあたり初心者スレらしくて微笑ましい List<int> suuji に入ってる一桁、数百の整数リストを3個ずつに纏めて新たなList<int> suujibunkatuに入れる作動を希望
C#の仕組みを理解するためにいろいろな方法を試しています
以下ソース
List<int> suuji = new List<int>();
//この後、suujiにはLoopで回した一桁の数字が数百入ります
List<int> suujibunkatu = List<int>();
foreach (var unit in suuji.Chunks(3))
{
Console.WriteLine(unit);
suujibunkatu.Add(unit);
}
//以下ネットからコピペした拡張メソッド
public static class Extensions
{
// 指定サイズのチャンクに分割する拡張メソッド
public static IEnumerable<IEnumerable<T>> Chunks<T>
(this IEnumerable<T> list, int size)
{
while (list.Any())
{
yield return list.Take(size);
list = list.Skip(size);
}
}
} やりたいことはforeachの中でList<int>suujibunkatu に三個ずつに纏められたunitの中身を次々に入れていく作動です
ここで、以下のエラーがでます
引数 1: は 'System.Collections.Generic.IEnumerable<int>' から 'int' へ変換することはできません。
場所はsuujibunkatu.add(unit)のunitに赤線になります
引数1 はList<int> suujiの最初の数字である1だと思います。
どうやって解消したら良いでしょうか?
unitに入ってるのがint[]のような配列だと思うのですが…それが原因なのかもわかりません
int[]に入ってる配列をint化する必要があるという感じでしょうか?
拡張メソッドの中身はまだ理解できてないので、拡張メソッドの方を改造しない方向で、のちのち拡張メソッド内を把握していこうと思っています
3つずつまとめる他の方法は出来るのですが、この拡張メソッドの中身を把握するために、使う部分でのエラーをなくしたいと思ってます
よろしくお願いします >>890
List<int> suujibunkatu = List<int>();にint[]をAddしようとしてエラーになってる
3つずつ格納するならList<int[]>にしないと エラーメッセージに全て書いてあるのに何で読まないんだろ >>891
うぉぉおできました
ありがとうございました
なるほど… リスト入れ子で使ってたけど、最近はクラスで中身決めてから使うようにしてます・・・ ディクショナリリストリストディクショナリディクショナリリストリスト… 女性客はリストの演奏で興奮のあまり失神者多発だったからなあ 練習でコンソールアプリケーションで迷路のようなのを作ってます
開始からゴールまでの時間を表示することはできたのですが、これを毎回記録しつつ、あなたは○○秒です〜現在○位です!
のようなランキングを表示できたらと思ってますが、どのような方法が考えられるのでしょうか? >>906
MySQL使ってDB構築してるわ
DB構築、そこからプレイヤーのidをキーに保持して、秒を保存すればええんでね?
ランキングはListとかでソートしてインデックス+1で表示
同率とかの処理必要ならメソッド作る感じで
オススメのDBはよく分からないけど >>906
1. 記録はファイル出力/ 順位表示時に毎回ソート
2. SortedList等を使って記録時にソート済みでファイル出力、起動時等にSortedListの構築が必要
3. DBに記録、順位表示はDBからソートした結果を取得して表示
自分だけでプレイするのなら1で十分だと思うが
練習なら上から順番にやっていくのでもいいかもね
DB使うならSQL CEかSQLiteかな ブラウザに記録する、Web Storage
どこかのサイトのランキング・サービスとか つか、その程度のデータならxmlかjson使ってクラスをシリアライズするのが良いよ 適当なBaaS使うのが簡単だろうね
やる気があればAWSで API Gateway + Lambda + DynamoDB ならほぼメンテナンスフリーで余裕で無料枠に収まる @ 記憶媒体からデータを読み込む。読み込んだ順番を保ちつつリストを作成する
A ゲーム開始→終了
B @のリストの先頭から見て行き、新しい記録より大きい要素の1つ前に挿入する。(挿入した位置が順位)
C 表示処理
D リストデータを記憶媒体へ書き込む
ソートは不要。
DBを使う要件がないのであれば記憶媒体はtxtファイルで十分。 >>906
テキストファイル名に名前秒数を適当な区切りを入れて保存
山田,60,田中,75,伊藤,81.scr
エクスプローラーからF2で編集可能
エディタもいらない
もちろんファイル名に使えない文字はあらかじめ除外だ ネットを見ていたら、インターフェースで依存性を排除するコードが
例として出ていたのですが「コンストラクタでengineに実装を注入する」とある部分は、どのように書けるのでしょうか?
インターフェースには実装が書けず、コンストラクタでメソッドを書くこともできないので見当がつきません
よろしくお願いします
public interface Engine
{
void start();
}
public class Car
{
public Engine engine;
public Car()
{
// コンストラクタでengineに実装を注入する
}
public void go()
{
engine.start(); // <- Engineはインターフェースなので依存性がなくなった
}
} Engineインターフェースを実装したエンジンのインスタンスを
何らかの手段で手に入れてengineに代入しろってことだな
つまり、君の買った車にはエンジンが付いてないので
買ってくるか、自分で作るか、好きにしてもらったらよいが
エンジン作る部分までは説明しないよ、ってことだな >>915
CarはEngineに依存してるよ
インターフェース使えばEngineの実装には依存しないようにできるけど
インターフェースなので依存性がなくなったというのは認識として間違ってると思う
んで実装を注入する方法はいくつかあって、例えばコンストラクタ・インジェクションなら
Carインスタンスを生成するときにEngine実装のインスタンスを渡してあげるイメージ
public Car(Engine engine) >>915
依存性云々はとりあえず今は聞き流して、インターフェイスの使い方を覚えるのがいいねw >>915
基本的にフィールドをpublicにしちゃだめ
メソッド名はPascal
質問とは無関係だけど >>915
なんで依存性を無くしたいの?
変更が必要になったら変更に必要なお金を貰えばいいじゃない?
君が依存性を無くした機能が将来的に役に立つ可能性は100%なの? >>921
こういう質問からズレた的はずれなこと言うやつってどこにも湧くよな
yahoo知恵袋とかにも多いけど 初心者スレだし
意味のないことをやってる人間を止めるのも優しさだろ
明らかに意味がない >>921
将来保守される保障あんの?
で、突き詰めたらメインメソッドだけで良いという結論に行き着きそうだな >>924
実際、機能10個作って10年で内3つしか変更が入らないときって
残りの7つに費やした依存性解消の時間って無駄じゃね?
いつ精算できんの?
変更することになってからゆっくり金貰って変更すればいいよ
予めやっておく必要も金も時間も欠片もない >>921
え?ユニットテストしないの?
まじかよ >>915 を書き直すとこういう感じだろうか
public class Car
{
private Engine engine;
public Car(Engine engine)
{
// engineのインスタンス生成は外部で行い、
// その参照をEngineインターフェースの変数として保持する
// (渡されたクラスにEngineインターフェースが実装されているか
// どうかしか感知しない)
this.engine = engine;
}
public void go()
{
// コンストラクタで渡されたEngineを使うので、
// インスタンスの実装には依存しない
// (実際に渡されるクラスで変更があっても、
// それがEngineインターフェースに関わらない部分なら影響がない)
engine.start();
}
}
あと、↓に従ってくれると、他の人からも読みやすい
インターフェイスの名前付けのガイドライン
https://msdn.microsoft.com/ja-jp/library/cc433279(v=vs.71).aspx
"インターフェイス名には、この型がインターフェイスであることを示すために、プリフィックス I を付けます。"
メソッドの名前付けのガイドライン
https://msdn.microsoft.com/ja-jp/library/cc433282(v=vs.71).aspx
"Pascal 形式を使用します。" >>927
命名規則持ち出すんなら、メソッド名もPascalにしろよ
それからフィールドはreadonlyにして_engine、thisは消せ >>926
依存先を先に作ればいいだけだよ
まさかDI使うプロジェクトは作るクラス全部疎結合にするとでも思ってるのか? 下位のモジュールを結合した状態で単体テストするのはおかしなことではないでしょ
MSだって普通にクラスの中でnewしてるよ
見境なくDIすると結合したときとのギャップが大きくなりすぎる
○○サービスと呼べるような粒度の低いクラスだけにとどめるのがいいと思ってる >>930
こいつUnitTestしたことないだろ 粒度も基準としてはあるが
自前のコードで完全に制御できないものはどこかで注入したほうがいいな
注入は別にインターフェースでなくてもいい
単にoverrideでもdelegateでも用途(今の文脈だとユニットテストか)に合えば良い
古い言語だとテスト用のモジュールをリンクしたり
マクロやインクルードで注入することもある >>934
単体テストと結合テストの違いはテストケース
単体でも通るテストか、結合してないと通らないはずのテストか、それだけのこと
開発順序の都合とかネットワークに依存しててクソ遅いとか意図的に発生させるのが難しいエラーがあるといった特別な理由がない限り、
単体でも通るテストを結合して動かすことはなんら単体テストの意義を損なうものではないよ 職場はユニットテスト何それ?だから1メソッドが数百行どころか千行超えるコードざらに見かけます・・・ >>936
結合してテストして失敗したら
テスト対象が悪いのか依存先が悪いのか切り分けが面倒だろ
やれやれだぜ >>939
よく考えよう
それ結合テストで起きる問題を先送りにしてるだけだろ?
むしろ単体テストレベルで見つかったほうが範囲が絞られてる分原因を特定しやすいよね ワッチョイ b769-ZN1Y)
ワッチョイ 236e-nkYL)
ブーイモ MM26-nkYL)
w >>938
わかる
汎用機型のプログラミングから抜け出せなかった企業はこれからどんどん終わってくよね >>926
それしないとユニットテストってできないの?
無駄なことやってない?
使い方知らないの? 質問者そっちのけで盛り上がってるねw
>>915が読んだ記事の著者のいう依存性の排除っていうのは恐らく、
Enineのコードが修正されてもCar側のコードがその影響を受けないようにする、
っていう程度の意味。(CarとEngineは別の人やチームが書いてると考えて)
そのための手段として、Carのコードでは具体的なクラスEngineではなく、
Car側のコードを書いている人、または第三者が定義したIインターフェイスEngineを使い、
EngineにはIEngineの実装を強制する。
そうすればEngineを書いている人はIEngineによって拘束され、
Car側(Engineを使う側)のコードが動かなくなるような変更はできなくなる。
まあたぶんこんな感じ。
だけど、下位の側のコード(この場合はEngine)を拘束するために
わざわざインターフェイスを使って抽象度を上げる(つまり可読性は下がる)必要が
本当にあるのかは、個人的にはかなり疑問。鶏を割くのに牛刀を使う感がある。
まあ質問者に確実に言えるのは、上にも書いたけど
依存性云々なんて理解しなくても問題ないから安心して読み飛ばしていいよってことw 依存性をどっかで断ち切らないと、変更の影響が波及し過ぎるからだよ
その例で言うなら、Carの実装内容がEngineに直接依存してると
Engineを修正した時に、Carも修正しなくちゃならなくなるので、それを断ち切りたい訳だ
実際には、その2クラス間にしか依存関係が発生しないなら纏めて修正でもそこまで困らないんだけど
クラスAにクラスBが依存、クラスBにクラスCが依存、クラスCにクラスDが依存……って連鎖してく様な形になってると最悪で
クラスAを修正した結果、クラスB〜Dも全部修正とかになる可能性がある すまん
汎用機は細かくプロセス分けて作るから単体テストはわりと容易だよ
そのノリでVBやJavaモノリシックなアプリを作ろうとしたところでおかしくなった >>947
設計変わってねぇのに
テスト数が増える話してんの?
ないとは言い切れないないけど考慮に入れるには頭悪くね? >>951
まともじゃない人って
何年もビジネスでやってるのに
金にならないプログラム組む人? 未だにVB5の保守案件を手放せていない俺は、きっとまともじゃないです 1秒毎にボーリング処理するなかであるクラスのメソッドを呼び出す場合、毎回newするのは悪手ですか?staticが基本でしょうか? 自分で分かってるくせに
中身をしらん俺には答えは分からんがな >>957
staticってのは意味不明だけど(フィールドじゃないの?)
基本的にどっちでも書きやすい方でOK
もちろん高価な共有リソースを使う場合は別 >>957
重いリソース抱えてないなら毎回インスタンス作って良いよ >>957
new のコストが重いならこんな手も
方法: ConcurrentBag を使用してオブジェクト プールを作成する
https://msdn.microsoft.com/ja-jp/library/ff458671(v=vs.110).aspx >>957
そのメソッドをアクセスしやすい場所に置けばいいだけじゃないの?
単純に使うクラスにメソッドをコピーするか必要なメソッドだけ分離してクラスにして今まで使っていたクラスではフィールドで持っておけばいい >>957
>>958の言うとおり
1秒毎にポーリングする処理というだけでは
毎回newするのが悪手かどうかstaticメソッドにするのがいいかどうかは誰も分からない
1. どういう選択肢があるのか考える(調べる)
2. それぞれのメリット・デメリット/トレードオフを理解する
3. 状況や目的に最も適している選択肢を選ぶ
こういう選択思考を繰り返すのが設計・コーディング時の考え方の基本
他にも選択肢あるから怠けず1.からやるのがいい
状況や目的をきちんと提示すればいいアドバイスが貰えるかもね もう実際にやってパフォーマンスモニタでログでもとってみりゃいーじゃん的な パフォーマンス的に問題ないかを確認するのが目的ならね。 JSON のシリアライズで教えてください。
派生先クラスのインスタンスを、派生元クラスのシリアライザで処理できないでしょうか。
こんなクラスがあるとします。 (書き方については大目に見てください)
class Data;
class ItemData : Data;
これをこんなことは出来ない物でしょうか。
var data = new ItemData();
(new DataContractJsonSerializer( typeof( Data ) )).WriteObject( stream, data );
この場合なら、こんな風に回避できるのですが。
(new DataContractJsonSerializer( data.GetType() )).WriteObject( stream, data );
こんなクラスのインスタンスに (AssemblyDataのインスタンス).data = new ItemData(); でシリアライズしようとすると実行時にエラーになります。
class AssemblyData
{
public Data data {set; get;}
}
ネットで見た範囲では DataContractJsonSerializer は多態に対応していると書かれた記事もあったのですが、どうにもうまくいかず。
方法があるようでしたら教えてください。 EventArgsとか毎回newしてるし全然問題ないでしょ >>966
例外メッセージにどうすれば良いか書かれてると想うけど
> DataContractSerializer を使用している場合は DataContractResolver を
> 使用することを検討するか、静的に認知されていないすべての型を既知の型の
> 一覧に追加してください。このためには、たとえば KnownTypeAttribute 属性を
> 使用するか、シリアライザーへ渡される既知の型の一覧にこれらの型を追加します。 newの質問したものです。
newにかかるオーバーヘッドの時間調査して、パフォーマンスを比較するのを怠ってましたが、やはりやってみないとわかりませんね。
やります。皆さん色々アドバイスありがとうございます。 いやいやいや、それはどっちかというと頓珍漢な言い掛かりの部類でアドバイスじゃないと思うよw
今年は何年よw
コンストラクタ呼び出しが時間的に高コストなんてよっぽど特殊なクラス以外ありえないよwww
µsオーダでもmsオーダーでもなく、たった1回/秒の呼び出しなんだからw
だから最初から言ってるように、普通は書きやすい方法で書いて何も問題ないよ本当。 いわゆる無駄な最適化の部類だとは思うが
まぁ自分で検証するというのれは良いことなのでどんどんやるといい >>970
いや、気にしてるのはnew連発の穴ボコメモリだろ?
そのうちosがうまいことやってくれるのはなんとなくわかるがそのコストって具体的にどうよ?
ってのが本当に知りたいことだろ?
環境次第だしパフォーマンスモニタ動かしてみろよって話
3日も動かすと5秒だけ動作が止まるような動きをするってなったらそれが運用上許容できるのか?バグるのか?
それもやっぱりやって見なきゃわからないんちゃうん? >>972
何がいやか分からないけど、だから最初から
高価な共有リソースを使う場合は別だと言ってるでしょ
今頃何を言ってるのかね
そういう例外的なケースを除けば、毎秒数個のオブジェクトを使い捨てにしたって
問題なんか起こらない。
そんなのXPの時代だってそうだから データベースへのコネクションを using で括ると
コネクションプールが機能しなくなる? >>973
問題起こらないってどういう範囲で言ってるの?
何度も確保したnewの領域をosがどう処理するから問題ないって言ってるの?
仕様によっては問題起きるよ
1つはメモリ限界ギリギリまでガベコレしないときは定期タスクの動きを止めてメモリ処理するよ
1分以上止まっちゃってたことあるよ >>975
具体的にどうぞ。
君が問題が起こる具体的な一例を挙げればそれで話は終わる。
もちろん、極端な特殊例でなくどこでもありうるような一般的なものでお願いしますよ。
あのねえ、今はPC-98の時代じゃないんですけどw とりあえずガベコレ動くときにプログラムの動作止まっちゃうよって1つあげてるよね >>978
すぐに使い捨てるなら確実にGen0GCで回収されるから止まる原因になることはないよ レス数が950を超えています。1000を超えると書き込みができなくなります。