C#, C♯, C#相談室 Part42
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2007/08/26(日) 12:42:25前スレ
C#, C♯, C#相談室 Part41
http://pc11.2ch.net/test/read.cgi/tech/1184840053/
過去スレは>>2-5あたり。
0282デフォルトの名無しさん
2007/09/03(月) 20:13:55return value + 2;
}
でいいじゃん
0283デフォルトの名無しさん
2007/09/03(月) 20:20:090284デフォルトの名無しさん
2007/09/03(月) 20:20:500285デフォルトの名無しさん
2007/09/03(月) 20:22:57変に例える必然性なんて全然ないのにね。
0286デフォルトの名無しさん
2007/09/03(月) 20:24:320287デフォルトの名無しさん
2007/09/03(月) 20:26:090288デフォルトの名無しさん
2007/09/03(月) 20:26:40あるいは逆にコレクションに変更を加えようとしてミスるプログラマが出るのを予防するためだな。
D言語ではforeachの制御変数には明示的にrefキーワードをつけないと、代入できないようになってる。
0289デフォルトの名無しさん
2007/09/03(月) 20:30:550290デフォルトの名無しさん
2007/09/03(月) 20:33:54そんなアホグラマは正直無視でいい・・・
と思うのは俺だけ?
だってそんなこといったら仮引数だって変更不可にするべきじゃん
0291デフォルトの名無しさん
2007/09/03(月) 20:42:45int opApply(int delegate(ref T));というメンバ関数を実装する。
http://www.kmonos.net/alang/d/statement.html#ForeachStatement
>>290
Dでは仮引数にinキーワード(あるいは、finalキーワード)を追加することによって、仮引数への代入が制限されますよ。
要するに、最近は酔っ払いでも使えるような言語設計が流行っているのだ。
0292デフォルトの名無しさん
2007/09/03(月) 20:50:440293デフォルトの名無しさん
2007/09/03(月) 21:01:280294デフォルトの名無しさん
2007/09/03(月) 21:45:38foreach (Hoge h in Hoges) {
h = new Hoge(); // はダメでも
h.Member = 123; // は全然OKだから
あまりガードにはなってないよね。
0295デフォルトの名無しさん
2007/09/03(月) 21:55:270296デフォルトの名無しさん
2007/09/03(月) 22:11:00なんかって何?一言主さん
0297デフォルトの名無しさん
2007/09/03(月) 22:13:01キャッチしなきゃいけない例外も必要だろ
C#はそういうのが意図的に外されてるんだな
意味ないから
0298デフォルトの名無しさん
2007/09/03(月) 22:15:50// cl /EHsc
#include <vector>
#include <iostream>
int main() {
std::vector<int> v;
v.push_back(1); v.push_back(3); v.push_back(5);
for each(int r in v) {
r++; // OK
std::cout << r << std::endl;
}
for each(const int r in v) {
r++; // Error
std::cout << r << std::endl;
}
}
0299デフォルトの名無しさん
2007/09/03(月) 22:18:01いや、チェック済み例外は明らかに設計ミス。
0300デフォルトの名無しさん
2007/09/03(月) 22:21:40絶対に間違いが起きる可能性がある処理はあるわけじゃない
そういうのをどうやって実装すればいいの
0301デフォルトの名無しさん
2007/09/03(月) 22:27:25済むことじゃないの?
まあ、それ以前にドキュメントをちゃんとして欲しいよねw
0302デフォルトの名無しさん
2007/09/03(月) 23:09:05見せる)シグニチャである点。
0303デフォルトの名無しさん
2007/09/03(月) 23:15:15あんた、単なる素朴な疑問かと思ってたけど
真正のあほだな
0304デフォルトの名無しさん
2007/09/03(月) 23:16:10オフラインでMSDN見ることってできないんですか?
0305デフォルトの名無しさん
2007/09/03(月) 23:21:540306デフォルトの名無しさん
2007/09/03(月) 23:31:16意味がよくわからないから詳しく説明してくれ
0307デフォルトの名無しさん
2007/09/04(火) 01:41:01constだので縛ってもバグは斜め上からやってくるね。
sealedつけてたのにsealed外されるとか。
foreachといえば、配列に関してはfor文と同等の速度が出ますが、こういう情報はどこにあるのでしょうか?
パフォーマンスガイドラインに重いループではforeachよりforって書いてあったので
わざわざ変えたのに・・悲しい。
0308デフォルトの名無しさん
2007/09/04(火) 02:21:04http://msdn2.microsoft.com/en-us/library/ms998547.aspx
1.1に基づいてるからまだforが速いって書かれてはいるが・・・
http://msdn2.microsoft.com/en-us/library/aa137140.aspx
ここにもパフォーマンスの記事が結構たくさんあるね
特にKnow What Things Costは命令ごとのコスト表が載ってて面白いかも
0309デフォルトの名無しさん
2007/09/04(火) 02:52:522.0だとforeachのほうが若干早くなってますね。
foreach (int v in ar) csum += v;
for (int i=0; i < 10000; i++) csum += ar[i];
これを下のように書くとforeachと同じスピードになるからそういう最適化をしてるのでしょう。
fixed (int *sp = &ar[0]) {
int *ep = sp + 10000;
for (int *p = sp; p < ep; p++) csum += *p + j;
}
ただ、foreachの制御変数が読み取り専用なのは、フェイルセーフのためなのか、
最適化のためなのかは判断がつきません。
0310デフォルトの名無しさん
2007/09/04(火) 07:54:38なるほど、「処理を直接記述されると最適化できないが
抽象度を高くすると最適化しやすい」というやつか
forよりforeachの方が早い
LINQも早くなるという
しかしループ変数への代入を許すとこの最適化が出来なくなるわけか
0311デフォルトの名無しさん
2007/09/04(火) 09:28:17EventWaitHandle.Handle プロパティで
ネイティブのハンドルを取得しようと思ったのですが、
「古い形式です」と起こられてしまいます(警告)。
新しい形式ではどのように書くのでしょうか?
0312デフォルトの名無しさん
2007/09/04(火) 09:37:04MSDNにずばり書いてあるから、まず自分で調べるくせをつけろ。
0313デフォルトの名無しさん
2007/09/04(火) 09:37:06EventWaitHandle.SafeWaitHandle.DangerousGetHandle()
でいいみたい。
Safeなんだか、Dangerousなんだか。
0314デフォルトの名無しさん
2007/09/04(火) 10:15:09DangerousGetHandle()は必要?
MSDNでは、
>このクラスを使用すると、派生クラスのインスタンスでラップされたアンマネージ リソースを
>識別するハンドル (オペレーティング システム ハンドルなど) をアンマネージ コードに
>渡すことができます。
となってるし、使用例にあるWindowsAPIの呼び出しサンプル見ても、IntPtrの代わりに使ってる。
というか従来のIntPtrの代わりに使うべきもののように見える。
DangerousGetHandle()はデバッグのためにハンドル値を16進でダンプしたいとかの特殊用途のために
残してあるんじゃないか。
0315デフォルトの名無しさん
2007/09/04(火) 11:08:29なるほど。ほんとだ。
ハンドルは、PVOIDだろ、と、
[DllImport("native.dll")]
public static extern void NativeFunc(System.IntPtr hHandle);
して、Handleプロパティから渡していたので、、
替わりにSafeWaitHandle使えと言われても、型が違ってこまってました。
[DllImport("native.dll")]
public static extern void NativeFunc(SafeWaitHandle hHandle);
こうすればいいんですね。
0316デフォルトの名無しさん
2007/09/04(火) 12:42:530317デフォルトの名無しさん
2007/09/04(火) 13:35:000318デフォルトの名無しさん
2007/09/04(火) 18:41:40正直、「ボキュはキモヲタだお」って言ってるようにしか聞こえない。
そういうの気色悪いと思わない自分を気色わるいと感じるべきだ。
0319デフォルトの名無しさん
2007/09/04(火) 18:48:43Label1.Text = Replace(Session("body"), vbCrLf, "<br />")
-----------------------------------------------
VBの本の中にソースが載っていたのですが、
この1文が、どうにもわかりません。
そのコード意味は、どうやらセッションというデーター内の改行を
HTMLの改行に変換するっぽいのですが・・・。(推測)
ちなみに、他の行は自力で調べましたが肝心のこのコードが分りませんし、
C#でどう書けば良いのか分りません。
賢者の方々、どうか愚者の私にご指導をお願い申し上げます
0320デフォルトの名無しさん
2007/09/04(火) 18:54:20少しはググるとか努力しろよ
VB.NET固有の関数をC#で使用するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/254vbfunc/vbfunc.html
でも、それただの部分文字列の置換でしょ?
String.Replaceか正規表現で代用できるでしょ。
0321デフォルトの名無しさん
2007/09/04(火) 18:54:33http://zoosir.hp.infoseek.co.jp/tips/string/string03.htm
C#だと省略可能引数(Optional)が無いから、全部書く必要があるらしい。
0322デフォルトの名無しさん
2007/09/04(火) 21:35:51MSDNも普通にフリーとして公開されてなかったか?
0323デフォルトの名無しさん
2007/09/04(火) 21:54:39C:\windows\Microsoft.NET\framework\以下にあるのでそんな気がしますが。
0324デフォルトの名無しさん
2007/09/04(火) 21:57:130325デフォルトの名無しさん
2007/09/04(火) 22:03:35おお、そうだったんですか。
これで安心してCodeDomが使えます。
0326デフォルトの名無しさん
2007/09/04(火) 22:17:14標準なのにドマイナーなのがひとつ
0327デフォルトの名無しさん
2007/09/05(水) 00:09:57ループの中から呼んだりして大丈夫なんだろうか。
何千何万って呼んだらなんか嫌なことになりそうな気がする。
0328デフォルトの名無しさん
2007/09/05(水) 00:15:47説明調の、他人に意味がちゃんと通じる文章書けよ
0329デフォルトの名無しさん
2007/09/05(水) 00:23:22それは説明するまでもないと思ったけど。
何が通じてないのかわからん。
Invoke系のメソッドってのはInvoke、BeginInvokeのことだよ
それらを呼んだら内部的に生成されるオブジェクトでファイナライザが呼ばれるっぽいんで嫌だなって話。
0330デフォルトの名無しさん
2007/09/05(水) 00:37:100331デフォルトの名無しさん
2007/09/05(水) 00:38:28読む側の立場に立って自分の文章推敲できない人間はたいていそうだ。
ついでに、ファイナライザのコスト?
意味がわからない。
デリゲートを処分するコストがそんなかかるのかね?
仮にかかるとして、コストとは「時間当たりのCPUの使用量」のことだと思うが、
どのみちmsのオーダーでInvokeとか不可能だから意味がないだろう。
0332デフォルトの名無しさん
2007/09/05(水) 00:39:31いったいどんな頻度でControl.Invokeなんかを実行する気だ?
0333デフォルトの名無しさん
2007/09/05(水) 00:44:23再描画を伴わないControl.Invokeの使い道って
あんまり思いつかないんだけどどうだろ?
経験上、何千何万って単位でControl.Invokeを呼ぶと
再描画コストが恐ろしいことになる。
WinFormsなら1秒間に10回ぐらいの更新でいいんじゃないかね?
まあそれ言い出すとTimerでいいじゃんて話も多いんだけど。
0334デフォルトの名無しさん
2007/09/05(水) 00:44:31CLR Profilerで見れるよ。
>>331
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/dotnetgcbasics.asp
この辺でも読んでくれ。
なんでデリゲートが出てくるのかわからんが・・・
>>332
別スレッドでなんかの処理中にUIを更新するために呼んだりしない?
まあ何万は言いすぎかも。
0335デフォルトの名無しさん
2007/09/05(水) 01:04:23ヘルプから見れるキーワードとか目次がMSDNなんですか?
0336デフォルトの名無しさん
2007/09/05(水) 01:05:13読んでくれって、どこにもお前さんが主張しているような類のことは書いてないだろw
0337デフォルトの名無しさん
2007/09/05(水) 01:10:27Control.Invokeを使ったらファイナライザが実行されたってこと?EndInvokeしてても?
0338デフォルトの名無しさん
2007/09/05(水) 01:13:32Control.Invokeで実行されるというファイナライザを持つオブジェクトが内包するオブジェクトとか。
Control.Invokeを実行する通常の頻度とかから考えて、それが問題になるほどコストが高いとは思えん
ということだよ。
「ファイナライザのコストが高い」という表現自体をそのまま疑ってるんじゃない。
ついでにEndInvokeしたらファイナライザは実行されないんじゃないの?普通に考えて。
と思っただけで、まあこれはプロファイラで確認してそうなってるってんならそうなのかもしれん。
0339デフォルトの名無しさん
2007/09/05(水) 01:17:46VS2005 Expressのヘルプに標準で何が入っているかは知らないが、MSDNライブラリはこれ。
ttp://www.microsoft.com/downloads/details.aspx?FamilyID=b8704100-0127-4d88-9b5d-896b9b388313&DisplayLang=ja
2.5Gバイトほどあるから注意してくれ。
0340デフォルトの名無しさん
2007/09/05(水) 01:22:22GCを二回行わなければならず単純計算でGCにかかる時間が倍になるんじゃなかったか
0341デフォルトの名無しさん
2007/09/05(水) 01:27:36>>338
EndInvokeしても呼ばれるみたい。
やっぱgen0でちゃちゃっと回収されるから問題が少ないってことなのかな?
具体的にはControl.ThreadMethodEntryってオブジェクトだけど
ファイナライザの処理自体はシンプルだけど他のオブジェクトへの参照は割とごっそり保持してるみたいだな。
まあ他に代替手段があるわけじゃなしどうこういっても仕方ないんだけどね。
0342デフォルトの名無しさん
2007/09/05(水) 01:42:58いらねーじゃねーかよ。
0343デフォルトの名無しさん
2007/09/05(水) 01:48:44そんなに困らないオブジェクトが多いけどな。
まあ引数とか戻り値はクリアしてほしいところだが
0344デフォルトの名無しさん
2007/09/05(水) 01:58:26GUIアプリだし、特にControl.Invokeなんて同期実行なんだから、まあ普通はまずGEN1ですべて回収できるだろう。
0345デフォルトの名無しさん
2007/09/05(水) 02:05:060346319
2007/09/05(水) 11:20:12一応、下記ソースに変更出来ました。
的確な助言、ありがとうございました。
if ((string)(Session["Body"]) == null)
{
Label1.Text = "<br />";
} else {
Label1.Text = ((string)(Session["Body"])).Replace("\r\n", "<br />");
}
0347デフォルトの名無しさん
2007/09/05(水) 11:24:430348319
2007/09/05(水) 11:45:52ご助言の通り、as演算子をしらべました。
お陰でたまに出るエラーがなくなりました。
さすがは神ですね。
即レスにも関わらず、100%的中でした。
なぜ、私がたまに出る意味が理解できないエラーで苦労している所を
お察し出来たのか愚民にはわかりませんが、
貴方の英知で、救われました。
再びお礼を申し上げます。
string s = (string)(Session["Body"]) as string;
if (s == null)
{
Label1.Text = "<br />";
} else {
Label1.Text = ((string)(Session["Body"])).Replace("\r\n", "<br />");
}
0349319
2007/09/05(水) 12:08:38string s = (string)(Session["Body"]) as string;
if (s == null)
{
LabelBody.Text = "<br />";
} else {
LabelBody.Text = s.Replace("\r\n", "<br />") + "<br />";
}
0350デフォルトの名無しさん
2007/09/05(水) 12:18:23string s = Session["Body"] as string;
じゃないとエラーでるっしょ
0352デフォルトの名無しさん
2007/09/05(水) 12:39:14エラーは出ないけど
string m = ((string)"Hello")
とはやらないだろって事じゃない?
0353デフォルトの名無しさん
2007/09/05(水) 12:59:04うん。私もそう思ったので、助言どおりに直しました。
だから、「助言ありがとう」とカキコしたよ。(^^
0354デフォルトの名無しさん
2007/09/05(水) 13:34:371. foreachのループの中でコレクションの書き換えをしたい。
2. foreachのループ変数を書き換えることによって、ループの制御をしたい
1.なら foreachのループ変数はコレクションの要素とは無関係な場合もある。
そもそも、IEnumerableには「要素」の概念はないし、arrayみたいにIListを実装した
インデックスを通じて要素にアクセスできるコレクションとは限らない。
2なら、ループのカウンタはIEnumerableの内部でループ変数とは別に
管理されているから、無駄(というか、おそらく何も起きない)。
だと思うんだけれど、ほかに何か書き込み許容するといいことってありますかね?
0355デフォルトの名無しさん
2007/09/05(水) 13:54:18ちゃんと読めとしか言いようがないが、1でも2でもない(つーか2は意味がわからんが)
あえて例を出すならこんなことがしたいんでしょ
foreach (string str in input)
{
str = str.Trim().ToLower();
if (str.Length == 0) throw new exception("Invalid");
Console.WriteLine(str);
}
0356デフォルトの名無しさん
2007/09/05(水) 14:15:34なるほど、そういうことか。全然議論が見えてなかった。
Console.WriteLine(str.Trim().ToLower());
でも書き込み禁止だとエラー出るのかな???
355さんの例みたいに条件分岐したいような場合は
たとえ書き込み禁止じゃなくても、可読性のために仮変数おいたほうが
いいとおもうけど…。
0357デフォルトの名無しさん
2007/09/05(水) 14:15:34object o = 1;
string s = (string)o as string;
0358デフォルトの名無しさん
2007/09/05(水) 14:29:43それはなんだ?
0359デフォルトの名無しさん
2007/09/05(水) 15:28:55ttp://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_03.html
のように、publicメンバすべてをラップしか、方法ありませんか?
0360デフォルトの名無しさん
2007/09/05(水) 15:30:100361デフォルトの名無しさん
2007/09/05(水) 15:36:46使うメンバだけラップすれば良いよ。
COM 化するって手もある。
0362359
2007/09/05(水) 15:53:00なるほどCOMって手も。。
説明まちがえた。
すべてのメンバか使うメンバだけって、ところが問題じゃなく、
いちどC++/CLIでラップしなければいけないのかどうか、知りたかった。
ラップするのはここではC++/CLIだが、
直接C#でラッパを書いて、マネージドのクラスライブラリを作ることは
可能ですか?
0363デフォルトの名無しさん
2007/09/05(水) 16:01:12C++/CLI でラッパを書く、C++ で COM 化するのいずれも避けるには?ってことですか。
ヘッダファイルとオブジェクトファイル(あるいはソースコード)で供給されるような普通の
良くあるクラスライブラリの場合、そもそもライブラリ側のコードを呼び出す手段が無い
ですよね。
dllexport されているクラスなら MSVC の ABI に従って呼び出してあげれば動くでしょうけど、
そういうライブラリはあまりないし、割に合わないような気がする。
0364デフォルトの名無しさん
2007/09/05(水) 16:34:36この DLL の Open 関数を構造体を引数として呼んであげると、この構造体の中にデータが入って
返ってくるというものです。
で問題はこの構造体のメンバに構造体の配列が入っており、この構造体の配列を取得することが
できません。( 構造体の他の int のメンバは取得できています。以下でいうところの ID )
このような構造体下の構造体を取得することはできないのでしょうか。
struct Parent
{
public int ID;
public Data[];
}
struct Data
{
public int RawData;
public int Length;
}
0365359
2007/09/05(水) 16:38:33すみません、最後の、
dllexport されているクラスなら(snip)動くでしょうけど、
について、もすこし教えてください。dllexportすれば、
C#から直接呼べますか?
0366デフォルトの名無しさん
2007/09/05(水) 16:59:15exportする側は
http://msdn2.microsoft.com/ja-jp/library/a90k134d(VS.80).aspx
あたりを参照
メンバ関数がどういう名前でexportされるかはコンパイラ依存。
dll 生成時の出来る lib を見て自分で調べる。
仮想メンバ関数は vtbl 経由でアドレスを取得。
MSVC の 呼び出し規約は基本 __cdecl ですが this を ecx に入れて呼ばなきゃないので、
そこだけは C++ というかアセンブラの補助が必要ですね・・・
0367デフォルトの名無しさん
2007/09/05(水) 17:00:01vtblに格納されているか少なくとも名前マングリングされたthisコールの
メンバ関数を起動し、スローされた例外を上手いこと取り扱い、最後に
デストラクタを起動して破棄できるのなら、C#でもきっと出来るだろう。
0368デフォルトの名無しさん
2007/09/05(水) 18:36:480369359
2007/09/05(水) 19:13:34みなさん。ありがとうなんとなく理解した。
[DllImport("native.dll")] extern static void Hoge()で、
C#から、Cの関数は呼べる仕組みがあるし(マーシャリングもあるし)、
マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、
なので、C#からC++/Nativeにアクセスできる方法も実はあるんじゃないかと、
ちょっと期待して質問してました。
0370デフォルトの名無しさん
2007/09/05(水) 21:11:06これはマジレス
キャストやアンマネージDLLを使うならVB.NETがいい。
VBFixedArrayにDECLAREで処理するDLLをC#で呼ぶ。
アンマネージVBが噛むと処理が激重だから、処理が軽いもの限定だけど。
FORTRAN
C
C++
で構造体処理するDLLも一発でいくよ
0371デフォルトの名無しさん
2007/09/05(水) 21:12:580372デフォルトの名無しさん
2007/09/05(水) 21:29:01アンマネージdllの関数呼ぶ手間はあんまり変わらないんじゃない?
0373デフォルトの名無しさん
2007/09/05(水) 21:32:03C++/CLIでやるのもありだな。2003ですまない
0374デフォルトの名無しさん
2007/09/05(水) 21:34:15それはVB.NETじゃなくないか?
0375359
2007/09/05(水) 21:38:27ラッパをVBで書く?
>>371
私もなんとなく同意。
やりたいことは、ネイティブなC++クラスライブラリを、
マネージド(C#)から使えるクラスライブラリにしたい。です。
結局C++/CLIでくるむ方法を取ることになりそうで検討中ですが、、
publicなクラス → ラッパクラス
interface → ??
publicなメンバ関数 → 全部ラッパ
publicなメンバ変数 → プロパティ
#define定数 → static const な定数
struct → ??
enum → ??
どのように書き換えたらいいか、わからないとこ満載だ。
どなたか、??のところを教えてください。
0376デフォルトの名無しさん
2007/09/05(水) 21:41:15同じかな?
0377デフォルトの名無しさん
2007/09/05(水) 21:43:47それなら2005を買ってみな。
ヘッダ読めばそのまま動く
0378デフォルトの名無しさん
2007/09/05(水) 21:48:34使いたいライブラリをC++でインクルード
コンパイル
C#で参照設定
.NETプロジェクト
これで全部使える
0379デフォルトの名無しさん
2007/09/05(水) 21:52:49(OBJECTだと通らないから注意)
で、きちんとした型をCTYPEで渡せば動作する
楽じゃないか?
0380デフォルトの名無しさん
2007/09/05(水) 21:56:22>マネージドであるC++/CLIからは、C++/Native のオブジェクトをnewできるし、
ネイティブのライブラリは実はCのランタイムライブラリが裏で色々サポートしているので
newの部分だけ見てても混乱するよ。
内部でCRTヒープ使ってるかもしれないし、
atexitみたいなコールバックに依存しているかもしれない。
一般論として、Cのライブラリは静的リンクなり動的リンクなりのCRTを必要とする。
そのCRTとの連携無しに、C#から
直接Cのコード使おうってのはちょっと無謀じゃないかな。
相手がDLLの場合、LoadLibraryされたときに自分でCRTの初期化やるから
その辺気にする必要はないんだけど。
0381デフォルトの名無しさん
2007/09/05(水) 23:44:08アセンブリをロードするとは思えんけど。
http://msdn2.microsoft.com/ja-jp/library/ms173266(VS.80).aspx
■ このスレッドは過去ログ倉庫に格納されています