C#, C♯, C#相談室 Part93©2ch.net
レス数が950を超えています。1000を超えると書き込みができなくなります。
■Visual Studio 2017 Community(無償の統合開発環境)等はこちら
http://www.visualstudio.com/downloads/
■コードを貼る場合はこちら
http://ideone.com/
■前スレ
C#, C♯, C#相談室 Part92
http://echo.2ch.net/test/read.cgi/tech/1485589613/
■次スレは>>970が建てる事。
建てられない場合は他を指定する事。
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured >>850
オブジェクトの値渡しってどういうこと?
参照型なら全部参照渡しになると思うが refだと渡し元が変更されるって十分な違いだろ
どうあって欲しいんだよ一体 >>850
ここらへんを見てみればいいかと
https://dobon.net/vb/dotnet/beginner/byvalbyref.html#section3
かんたんに言うとどっちでも渡されたオブジェクトの中身は変えられるけど、ref付けないと新しいオブジェクトを設定して呼び出し元に返せないってこと 参照値でも、refつけない値渡しとref付ける参照渡しできる。
で、参照値以外の値...とりあえず非参照値と呼ぶと
非参照値でも、refつけない値渡しとref付ける参照渡しできる。
全部で4パターンあるってこと 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b) >>850
簡単なので難しく考えてはだめ。すごくシンプルな話。
その型の値(その型の変数に格納される値)を渡すのが値渡し。
その型の変数の「場所」を渡すのが参照渡し。
さらっと書いたけど、「その型の値 = その型の変数に格納される値」なのはよく理解する必要がある。
つまり、参照型の変数に格納される値って何だったか要再考。
変数とはメモリ上に割り当てられた特定の領域のこと。
だからその領域のバイト列のコピーを渡すのが値渡しで、
領域の先頭アドレスを渡すのが参照渡しだと思えばいい。
参照渡しでメソッドが受け取る情報は「変数の」場所なので、参照渡しの引数に
リテラルや式を渡すことは出来ない。 多分だけど参照渡しと値渡しの挙動自体は理解しているものの、
デフォ参照型とデフォ値型の区別がついておらずにデフォ参照型で実験をしてrefでも素渡しでも変わらないやんってことじゃないか TryParseみたいなのだと成否と値がtupleで返って来てもifの中でめんどい メソッド内で中身を変更するって理由で参照型のもref渡ししてるのみてイラッとしたことはある。イランヤン それVB6からの移植とかじゃない?
オフショアが移植したコードがそんなんばっかし ref の使いどころってライブラリから複数の返値欲しい時だから
他の手段使えるならそっちでいいわな
未初期化変数指定できんのも地味にイラッと来るし >>861
そういう場合はrefではなくoutを使う >>861
> 未初期化変数指定できんのも地味にイラッと来るし
out使えよ 引数いじるの好きじゃないわ
返り値だけで判別させて まあ参照型はoutの制約で十分かつ安全なのでrefはほぼ出番ないんじゃねえのん
Swap関数を定義する時くらしか適切な例が思い付かねえ そのswapがな、MVVMでお決まりのBindableBaseなりのSetPropertyでプロパティの値交換するときに使いまくりで、
androidでもMVVM使いまくってるけどrefないkotlinやjavaでやると... プロパティの値交換するときってのが想像つかんが
どういうときにそれを使いまくるんだ? BindableBase SetPropertyとかでぐぐってみれ
有り体に言えば自身のプロパティ(のバックストア)を差し替えるジェネリックメソッドを基底クラスで定義するのに使うだけ WPFとかUWPとか使ってればBindableBaseのありがたさはよくわかる
関係ないけどstaticメソッドって呼び出すときにいちいちインスタンスを生成する必要がないって以外のメリットあるのかな? >>871
まあメリットって発想がそもそもおかしい。
例えばDouble.Parseがstaticなのはその方が意味的に自然だから
インスタンスメソッドである必然性がないし、インスタンスメソッドでは不自然だから dictionaryとかのcollection系が手抜きなのなんで?
特にdictionaryとか拡張必須だし
割とc#好きだけどこれはほんとアカン テンプレート系はデータが増えればC++にでも勝てるのに
何が問題? Collection系はJavaの方がしっかりしてるよね。 queueは空っぽの時取り出そうとすると落ちやがるの許せん勝田
今はTryあるからいいけど 例外が発生することを落ちるって表現する男の人って… 例外っていろんな種類あるけど具体的に何を使えばいいのかよくわからなくて
とりあえずcatch(Exception e)とかしちゃってるけど本来はこんなのダメだよな…… 別にいいと思うぞ。下位の呼び出しのどこかで失敗したということに対して適切に処置するなら。 >>883
> 例外っていろんな種類あるけど具体的に何を使えばいいのかよくわからなくて
投げる方で悩むのはわかるけど
> とりあえずcatch(Exception e)とかしちゃってる
受ける方はどれ受けるべきかはわかってるでしょ
最終手段としてよくわからんけどエラーが発生したから終了するね
って言うならcatch(Exception e)もありだと思うが 終了というのがプログラムの終了のことなら逆にcatchしちゃだめだろう。 >>887
catch { }ではw
>>888
例外一つでプログラム終了していたら大概困るw 例外はありえない事態なんだからプログラム終了しなきゃまずいだろう >>889
それは逆で、プログラマが想定してない例外が発生したら
プログラムは停止してもらわないと困る。これが正しい考え方。
そもそも例外機構というのはそのためにある 最近部活の後輩が黒魔術みたいなコードを書くようになって困ってるんだが対策ない?
こんな感じのコードを後輩が書いてくるんだよ↓
public interface IMessenger {
__public MessageReceived();
}
public abstract class Messenger : IMessenger{
__public abstract void MessageReceived();
__public abstract void Retry();
} public class Mail : Messenger {
__public override void MessageReceived(){
____//処理
__}
__public override void Retry(){
____//処理
__}
}
public class Alarm : Messenger {
__public override void MessageReceived(){
____//処理
__}
__public override void Retry(){
____//処理
__}
}
public class Communication {
__public void SendMessage(IMesssenger message){
____SendMessage(message);
__}
__public void Received(){
____var received = GetMessage() as IMessage;
____received?.MessageReceived();
__}
} こんなんだったから
public class Communication{
__public void SendMessage(string message){
____SendMessage(message);
__}
__public void Received(){
____var received = GetMessage();
______switch(received.First()){
_______case "0":
_________MailEvent(received);
_________break;
_______case "1":
_________AlermEvent(received);
_________break
____}
__}
}
こんな感じで書くように矯正しといた
CSVで2文字で分けるって言ってるんだから
何が起こってるかわかるように書くことを意識してもらわないと まあ例外でプログラムは終了させるべきだよな
ただ客は例外が起きてもcatchで握りつぶしてスルーした方が文句言わないんだよな…… >>892
酷いな
MediatoRを使うようにアドバイスしてあげなよ >>892
2chのシステムは先頭の半角スーペースは除去するけど全角スペースは除去しない。
だから字下げは後者で >>889
> catch { }ではw
ごめん、何を言いたいのかわかん
処理部分も当然必要だけど何を受けるかの話だから(Exception e)の方が重要だろ? >>891
ちょっとMSに例外じゃなくエラーコード戻す設計にするようお前から言ってきてくんね?
W32APIはそうなってんのにFrameworkの方そうなってないじゃん byte*からbyte[]にする方法ってない?
new byte[64];みたいに新規確保してコピーしか方法ないんだろうか
Unsafe.As等で新規確保無しで出来るかと思って色々試してみたけど上手くいかない 「byte[]にする」が「byte[]とみなして扱えるようにする」って意味なら
全然別の型なんだしあるわけないでしょう。
そういう危なっかしい機能を排除してるのがC#の売りの一つだったはずなわけで
コピーする機能ならMarshalあたりにあるんじゃない? >>902
>「byte[]にする」が「byte[]とみなして扱えるようにする」って意味なら
そういうことです
あるわけないと言いますが、その逆はあるので出来るかなと思い
(byte*やref byteで先頭を指定し自作のstructとして読ませる。少しずらせばbyte[]を自作クラスとして読ませることも可能) >>903
>(byte*やref byteで先頭を指定し自作のstructとして読ませる。少しずらせばbyte[]を自作クラスとして読ませることも可能)
具体的なコード希望 その逆がマネージドじゃ難しいからね
無理じゃないかなあ
やっぱこれからはSpanですよスパンスパン >>904
public struct MyStruct { public int Value1, Value2, Value3, Value4 };
byte[] data = new byte[16] { 1,0,0,0, 2,0,0,0, 3,0,0,0, 4,0,0,0 };
ref var myStruct = ref Unsafe.As<byte, MyStruct>(ref data[0]);
これでmyStruct .Value1は1、myStruct .Value2は2, myStruct .Value3は3, myStruct .Value4は4と余計なコピー無しに直接読み書きできる
byte[]からclassの場合はFieldOffset指定して各フィールドを4バイト後ろにづらないと出来ないから実用は難しいけど一応可能 fixed (byte* ptr = &data[0]) *(MyStruct*)ptr;
と大体同じではあります やっぱりこういうことやりたければC++に池ってことなのでしょうか
記憶力悪いのでVSがC#ほど助けてくれないC++に行くのは億劫なため質問させてもらいました byte[]も参照型だからね、オブジェクトヘッダが付いてなければ扱えない
Span<T>でなければ、具体的なシナリオにも依るけど元からbyte[]で作って
TypeHandleとlengthのsizeof(IntPtr)*2分ずらした所を使い回す方が賢明
結局fiexdと一緒な訳だが、P/Invokeならbyte[]渡してもゼロコピーの筈だし
abstract class Union<T> where T : struct {
internal readonly IntPtr length;
public T Value;
}
みたいなオレオレ実装をILキャストした事もあったな…後はSafeBufferとか self containedって完全に依存なしになるわけじゃないのね
alpine用にself containedでビルドしても動かなかった
libstdc++とか色々インストールしたら動いたけどさ
dotnetコマンド同梱と比較してコンテナサイズも殆ど変わらないし意味あるのかなこれ SCDは.NETのランタイムを別途インストールじゃなくて同梱するってだけの話だしね
公式ドキュメントにも注釈あるけどLinuxは仕様上完全に断ち切るのは難しいんじゃない?
Windowsだと同梱のファイルだけでそのまま動くけど >>913
Windows配布用と割り切った方がいいのかもしれない
Linuxだと管理下のサーバーかコンテナが多いからSCに拘る必要もない 最近のバッチはみんなSCDにしてる
らくちんらくちん ちょくちょくポインタ代替機能についての質問があるけどさ
どんな用途でポインタを使いたいのかわかんないけど、大抵の場合はストリームで代用できるんじゃないのかな ポインタなんかアンマネージとのやり取りとBitmapdataでしか使ったことないな
アンマネージとのやり取りだとrefとかoutにしとけばあとは何も考えなくていいから助かる 「変数aが1,4,5,7のいずれかである場合」
という論理式を書く場合
(a==1) || (a==4) || (a==5) || (a==7)
とswitch文以外でもっと手っ取り早く書く方法ありますか? >>923
その表現が一番端的でわかりやすいのではないですか? new [] {1, 4, 5, 7}.Contains(a) >>923
その程度ならその書き方が一番わかりやすいと思うが比較対象がもっと多いとか可変にしたいとかなら
var C = new HashSet<int>(){1, 4, 5. 7};
if(C.Contains(a)){ … }
とかもある >>924
数が少ないうちはいいんですが
>>925
カッコの上でShift+Ctrl+}すると
式部分を一発選択できるのであえてそうしてる
>>926
これがいい感じです
少しオーバーヘッドが気になりますが SQLみたく
a IN (1,4,5,7)
てかければいいなとおもうが、aが右側になっちゃうのが若干違和感 >>927以上の書き方ねーべ
オーバーヘッドなんぞ無きに等しい >>928
HashSetやDictionaryは要素の数に左右されない方法でアクセスを行うから
含まれてるか否かといったような検索用途に限定すれば1個だろうが1万個だろうが常に高速にアクセス出来る
Listや配列は要素数に比例してアクセス時間かかるようになるが なぜ要素数が増えることがある
という大前提を最初の質問時に明記しないのか >>926
これ、new[]の部分を()で括らなくていいのは何か直感に反するけど、
newもnew[]もドット演算子と同じ優先順位なのかw
キャスト演算子も同じ扱いにしてくれたらよかったのに >>932
もとの要素がどこにあるかよくわからんけどな
HashSet作成して要素セットするオーバーヘッドがあるだろう
格納時にハッシュ値計算するから比較のコストが低いわけで、その分格納にコストがかかるんだぜ 使い捨てなら配列のほうが安そうな気はするが
それが差となって現れるようなユースケースとも思えんしなあ 質問者ってそんなに偉いの?
そいつの質問に常に合致した話題じゃなきゃダメなの?
ひとつの質問があって、それを機会に派生してもいいし、あとは自由に意見しあえってもいい
どんだけ構ってほしいんだ 気にしてるの君じゃん
自由でいいと思うなら
かってにやってりゃいいじゃん
どんなけかまってほしいの? ROM専からすると多少横道にそれてもいろんな手法を見れるほうが面白い
正直これくらいの質問なら好きにしろって感じだろ >>935
だから検索用途ならって書いた訳だが
if ((a==1) || (a==4) || (a==5) || (a==7))って書けるってことはAddは頻繁に行わないと受け取ったわ 述語の部分が、
(1) 全要素を常に == で評価
(2) 全要素を同じ演算子で評価するが、==以外の演算子も使われる場合がある
(3) 要素ごとに個別の評価方法
で最適な答えが変わりそうなんでその辺ははっきりした方がよかったかもね。
質問者は
(a==1) || (a==4) || (a==5) || (a==7)
の代替案を聞いてるんだから普通に考えれば要素数はそんなに多くないはずで
パフォーマンス云々は風呂敷広げすぎだろうw 議論の途中で申し訳ないのですが
例えば独自クラスで、こんなのがある。
独自クラス{
string name {get; set;}
decimal num1 {get; set;}
decimal num2 {get; set;}
}
というのがあって、グリッドビューにList〈独自クラス〉をデータソースとして渡して表示させたいのですが
numは3,4,と増える可能性があります。(型はすべて同じ)
この場合にソースコードをメンテナンスすることなくnumの増減に対応するにはどのようにすれば良いでしょうか? decimal[] num {get; set;}
とか、
Dictionary<int,decimal> num { get; set; }
じゃダメなの?
なんか設計レベルで問題がありそうな気もするけど。 >>943
配列なりListなり使えばいいだけじゃねーの? 固定値でIFするのは好きじゃないな。
ソースの冒頭で定数を定義したい。 >>943
列が可変になるのならデータテーブル使うのが楽だと思う。クラスでやるとしたらexpandoで作るもなくはないと思うけど、それなら上にある通りDictionaryの方がシンプルではないかと。 >>942
質問者がオーバーヘッド気になるとか発言してるので、パフォーマンスを考慮することに意味はあるんじゃね
まあ、ずらずらと手書き出来る程度の要素数ならどれ使っても大差ないって言っとくべきではあるかもしれんが C#はセキュリティー的に問題があるので使わないほうがいい。 レス数が950を超えています。1000を超えると書き込みができなくなります。