C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: staticメソッドの仕様について?


(過去ログ 107 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■63929 / inTopicNo.1)  staticメソッドの仕様について?
  
□投稿者/ らぐんす (7回)-(2012/10/30(Tue) 10:44:01)

分類:[C#] 

staticメソッドについて質問です。

ある特定のクラス内でstaticメソッドを有するとき

public class Sample
{
 public static Test GetTest()
{
  var test = new Test();
  test.AAA = 1;
  test.BBB = 2;
  return test;
 }
}

例えばGetTestメソッドが10回呼ばれたとしてもSampleクラスが生きている限り、testのインスタンスが10個ともメモリに貯まっていくのでしょうか?
はい、いいえで構いません。どなたかよろしくお願い致します。
引用返信 編集キー/
■63931 / inTopicNo.2)  Re[1]: staticメソッドの仕様について?
□投稿者/ 774RR (11回)-(2012/10/30(Tue) 12:04:42)
これって単に Test クラスの変数を新規に作って返却しているだけぢゃん。
答えは「はい」でも「いいえ」でもない。提示コードだけでは判断できない。
当該 GetTest() の返却値をどう使っているか次第。

クラスが生きているってのもよくわからん表現だね。
プログラムの開始から終了まで、って意味にしかならんと思う。
引用返信 編集キー/
■63932 / inTopicNo.3)  Re[2]: staticメソッドの仕様について?
□投稿者/ howling (19回)-(2012/10/30(Tue) 12:25:10)
らぐんすさん

こんにちわ。結果自体は774RRさんのおっしゃる通りかなと。
新規に作成したクラスのインスタンスを返しているので、
そのインスタンスへの参照が無くなった時点でGC対象となって消去されるのかなと。
逆に参照をどれもこれもし続けているのなら、消去されないままなので、何とも言えません。

…シングルトンでもしたいのかなぁ…。
とすると、Testオブジェクトのインスタンスをprivate staticでメンバに入れておいて、
GetTestメソッドではその値を返せばいいのでは?

いや、そんなことする気じゃないんですよって場合はごめんなさい。

引用返信 編集キー/
■63933 / inTopicNo.4)  Re[3]: staticメソッドの仕様について?
□投稿者/ らぐんす (8回)-(2012/10/30(Tue) 13:46:08)
774RR様、howling様、ありがとうございます。
混乱しており、言葉足らずで申し訳ないです。

SampleクラスはWebサーバー側のプロジェクトにあります。
クライアント側のプロジェクトから
あるスレッド@が
Test test = Sample.GetText();
別のスレッドAが
Test test = Sample.GetText();
と利用していったとした場合にスレッド@が終了したら、GetTestメソッド内部のtestインスタンスはGCの対象になっているということでよろしいでしょうか?

staticがなければtestはただのローカル変数なので、GetTextブロックの終了とともに無くなると分かるのですが、
GetTextブロックにstaticが付くと、SampleクラスはIISを停止しない限り、testインスタンスがいくつも生成されたままの状態なのでは?と危惧し、質問させていただきました。


引用返信 編集キー/
■63934 / inTopicNo.5)  Re[4]: staticメソッドの仕様について?
□投稿者/ Hongliang (10回)-(2012/10/30(Tue) 14:28:24)
> SampleクラスはWebサーバー側のプロジェクトにあります。
> クライアント側のプロジェクトから
> あるスレッド@が
> Test test = Sample.GetText();
> 別のスレッドAが
> Test test = Sample.GetText();
> と利用していったとした場合にスレッド@が終了したら、GetTestメソッド内部のtestインスタンスはGCの対象になっているということでよろしいでしょうか?

// 表現的には、testインスタンスじゃなくて、test変数が参照するTestインスタンス。
スレッドはインスタンスの寿命と関係有りません。
このtestが指すインスタンスがそれ以外で参照されないまま、test変数のスコープを抜ければ、そのインスタンスはGCの対象になります。
要するに「誰も参照しなくなれば」です。

> staticがなければtestはただのローカル変数なので、GetTextブロックの終了とともに無くなると分かるのですが、
> GetTextブロックにstaticが付くと、SampleクラスはIISを停止しない限り、testインスタンスがいくつも生成されたままの状態なのでは?と危惧し、質問させていただきました。

staticが有ろうが無かろうが、このSample.GetTestのtestはただのローカル変数です。
C#ではローカル変数に対するのはフィールドですが、このtestはSampleのフィールドではありませんよね。
引用返信 編集キー/
■63935 / inTopicNo.6)  Re[4]: staticメソッドの仕様について?
□投稿者/ 774RR (12回)-(2012/10/30(Tue) 14:49:05)
> GetTestメソッド内部のtestインスタンス
なんてものは無いんだが、その辺に何か混乱は無いかな。

例示の Sample::GetTest という関数は static である = Sample のインスタンスなしに呼べる
というだけ。返却値である Test に static の効力は及ばない。

> staticがなければ
提示の public static Test GetTest() { ... } の static であるなら無関係。
> testはただのローカル変数なので、
そのとおり。

ガベージコレクタが「参照されなくなった」と判断したとき、処分対象になる。
C++ と違いブロックの最中でも gc される(ことがある)。
つまりスレッドが終わる以前に処分されることがある。スレッド終了まで存在し続ける保証は無い。

ところで GetText なのか GetTest なのかはっきりしないな。
とりあえず GetTest のことだと勝手に解釈させてもらった。
引用返信 編集キー/
■63936 / inTopicNo.7)  Re[5]: staticメソッドの仕様について?
□投稿者/ howling (20回)-(2012/10/30(Tue) 15:11:58)
2012/10/30(Tue) 15:14:20 編集(投稿者)

らぐんすさん

うーん…Webサーバーを介してのC#プログラミングは行ったことがないのですが、
どうも調べている状態では、オブジェクトの動作的には変わらないようです。
シングルトンでなければ、FactoryMethodパターンを使おうとしていらっしゃるのかな?と思うのですが、
C++でもC#でもそれは可能です。
おそらく、らぐんすさんも理解されていると思いますが、下記に一例を。


public class MeshClass
{
protected MeshClass(){}
public static MeshClass CreateMesh()
{
MeshClass clsMesh = new MeshClass();
//ごにょごにょ初期化
return clsMesh;
}//ここを抜けてもclsMeshを返しているので、それが参照可能な限りはGC対象とならない

public static void DestroyMesh(MeshClass clsDestroyData)
{
//消す前に何かするならここで処理
}
}

public void hogeMethod()
{
MeshClass clsFirstMeshData = MeshClass::CreateMesh();

//メッシュの位置変更とか。
MeshClass::DestroyMesh(clsFirstMeshData);
//hogeMethod内でclsFirstMeshDataをバインドや登録などの処理をしていない限りは、
//この時点でclsFirstMeshDataはGC対象となる(つまり、1回目で呼び出したclsMeshはこの先のどこかで捨てられる)
}

public void hunyaMethod()
{
hogeMethod();

MeshClass clsSecondMeshData = MeshClass::CreateMesh();

MeshClass::DestroyMesh(clsSecondMeshData);
//ここを抜けたらclsSecondMeshDataもGC対象(つまり、2回目で呼び出したclsMeshはこの先のどこかで捨てられる)
}



引用返信 編集キー/
■63937 / inTopicNo.8)  Re[5]: staticメソッドの仕様について?
□投稿者/ らぐんす (9回)-(2012/10/30(Tue) 15:40:51)
774RR様、howling様、ありがとうございます。
説明下手で本当申し訳ないです。
ひとまず心配する内容は杞憂に終わったということで…
お二人のおかけでだいぶ理解出来ました。
またよろしくお願い致します。

解決済み
引用返信 編集キー/
■63938 / inTopicNo.9)  Re[6]: staticメソッドの仕様について?
□投稿者/ らぐんす (10回)-(2012/10/30(Tue) 16:49:31)
Hongliang様、 howling様と同じ方と思いました。改めてお礼申し上げます。

howling様、入れ違いで投稿されたため後ろのスレについて質問させてください。

//hogeMethodが別のクラスにあるとして(C++知らないのでC#で書き直しております)

using MeshService;//MeshClassはWebサービスプロジェクト内部にあります。

//MeshClassはおよびMainはWindowsフォームプロジェクトにあります。
public class MeshClient {
 public void hogeMethod() {
  MeshClass clsFirstMeshData = MeshClass.CreateMesh();
  //MeshClass::DestroyMesh(clsFirstMeshData);
 }
 public void hunyaMethod(){
  hogeMethod();
  MeshClass clsSecondMeshData = MeshClass.CreateMesh();
  //MeshClass::DestroyMesh(clsSecondMeshData);
 }
}

static class Program {
public static void Main(){
  MeshClient mesh1 = new MeshClient();
  mesh1.hogeMethod(); //※Webサーバー内にMeshClassインスタンスが1個配置
  mesh1.hunyaMethod(); //※Webサーバー内にMeshClassインスタンスがさらに2個配置
 } //※Webサーバー内に配置された3個配置MeshClassインスタンスは解放されるはず
}

私の認識に間違いないでしょうか?よろしくお願い致します。



引用返信 編集キー/
■63940 / inTopicNo.10)  Re[7]: staticメソッドの仕様について?
□投稿者/ howling (21回)-(2012/10/30(Tue) 18:32:17)
らぐんすさん

すみません、私の書き方が悪かったかもしれません。
コードについては、元よりC#で書きました。
C++だとクラスの宣言後にセミコロンが必要だったり、publicなどの書き方も変わりますので、
結構色々と異なります。

結論としては、インスタンス自体はGC対象になるので、1つも残りませんよ、ということです。
ですので、前回書いて頂いた「杞憂に終わった」というので問題ないです。

//hogeMethodが別のクラスにある
そうですね、hogeMethodもhunyaMethodも別のクラスにあると思ってください。
hogeとかhunyaとかは、適当なメソッド名としてたまに使われるので。
int hoge = 0; みたいに使われることもあります。

>mesh1.hogeMethod(); //※Webサーバー内にMeshClassインスタンスが1個配置
>mesh1.hunyaMethod(); //※Webサーバー内にMeshClassインスタンスがさらに2個配置
ここだけ少し違いますかね…。
clsFirstMeshDataは、hogeMethod内のCreateMethod呼び出し後にどこからも参照が無いため、
その後のどこかでGCに破棄されます。
同じく、clsSecondMeshDataはhunyaMethodのCreateMethod呼び出し後にどこからも参照が無いため、
その後のどこかでGCに破棄されます。

ですので、特に問題はありません。
迷わせてしまったようで申し訳ありません。
引用返信 編集キー/
■63943 / inTopicNo.11)  Re[8]: staticメソッドの仕様について?
□投稿者/ らぐんす (11回)-(2012/10/30(Tue) 23:46:51)
howling様、ありがとうございます。

成る程、C#では私がコメントを付したデストラクタと同等の効果が望めるのですかぁ。
理解が深まりました。

この問題は解決済みということでクローズ致します。
howling様、Hongliang様、774RR様、この度はありがとうございました。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -