• 締切済み
  • 困ってます

.NET言語の定数について

記述の違い以外は.NETの言語共通の質問になるのですが、 質問はC#で質問いたします。 定数を表すのに const double PI = 3.14; static readonly double PI = 3.14; などと2つの書き方があるようですが、使い分けの 仕方がわかりません。 どのような場合に、どちらを使うものなのでしょうか?

共感・応援の気持ちを伝えよう!

  • 回答数3
  • 閲覧数220
  • ありがとう数0

みんなの回答

  • 回答No.3
  • Bonjin
  • ベストアンサー率43% (418/971)

とりあえず、C#のリファレンスには readonly キーワードは、const キーワードとは異なります。const フィールドは、フィールドの宣言でしか初期化できません。readonly フィールドは、宣言またはコンストラクタのどちらかで初期化できます。このため、readonly フィールドは、使用するコンストラクタに応じて異なる値を持つことができます。また、const フィールドがコンパイル時定数であるのに対し、readonly フィールドは実行時定数として使用できます。 と書いてあります。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • 特定のクラスだけで const 変数を有効にしたい

    円周率のような “意味を持つ定数” を C++ では以下のようにするのをよく見かけます。 const double PI = 3.1415926; これを特定の 1 つのファイル内だけで有効にする方法はありませんか? 例えばあるクラス Hoge.cpp と Hoge.h のみで上記の PI を使う,というように。 Hoge.h をインクルードするファイルにおいては PI を無効にしたいのです。 C++ 超初心者につき,マヌケな質問をしているかもしれないですが,ご教授願えたら幸いです。

  • C++言語のプログラムをfortranに変換

    const int N = 100; const double q = 10.0, dt = 0.00001, Dm = 30.0, t0 = 2.0, K = 1.0, pi = 3.141592, f = 3.0; double C[N], dC[N]; double dx = q/N; for (int i = 0; i < N; ++i) C[i] = 0; // 初期条件 for (double t = 0; t < t0; t += dt) {  C[0] = 0; // 境界条件1  C[N - 1] = K*sin(2*pi*f*t); // 境界条件2  for (int i = 1; i < N - 1; ++i) dC[i] = (Dm*(C[i + 1] - 2*C[i] + C[i - 1])/(dx*dx))*dt;  for (int i = 1; i < N - 1; ++i) C[i] += dC[i]; } for (int i = 0; i < N; ++i) cout << C[i] << endl; // t = t0 このプログラムをfortranに変換できる方いますか?

  • C#で、定数をフラグ(if文)によって切り替え

    C#ですが、カテゴリが無いのでC/C++のカテゴリに入れています。 基本的に変数(定数)の宣言は1回しか出来ないとわかっていますが、 以下の様な定義を何とかできないでしょうか? if (true) { public static readonly string Flag = "True"; } else { public static readonly string Flag = "False"; } これって、変数を使って、以下のようにするしか無いですよね…… public static string Flag = ""; if (true) { Flag = "True"; } else { Flag = "False"; } もしくは、変数で宣言した物を、途中で定数にする事は可能でしょうか? 目的としては、グローバルで宣言した変数を別の関数で変更されないようにしたいだけなのですが。 何か、手があれば教えてください。

  • 回答No.2

いきなり誤訳発見 >コンパイルするまで値がわからないような コンパイルの地点では値がわからないような

共感・感謝の気持ちを伝えよう!

  • 回答No.1

あまり意識した事がありませんでした。 http://blogs.msdn.com/csharpfaq/archive/2004/12/03/274791.aspx にまさにぴったりな記述がありましたので紹介します。 ただ、英文の意味が理解出来たような出来てないような。 一応和訳しておいておきますが、誤訳の可能性大ですので慎重に。 The C# team posts answers to common questions C#チームは一般的な質問に対する答えを投稿した What is the difference between const and static readonly? constと static readonlyの違いは何か? The difference is that the value of a static readonly field is set at run time, 違いは static readonly fieldは実行時にセットされると言うことだ。 and can thus be modified by the containing class, whereas the value of a const field is set to a compile time constant. constはコンパイルされた時の値に固定されるけど だから、含むクラスによって変更されることができるんだ。 In the static readonly case, the containing class is allowed to modify it only static readonlyの場合、以下の含むクラスが修正することがすることが許される * in the variable declaration (through a variable initializer) 変数宣言 * in the static constructor (instance constructors, if it's not static) Staticなコンストラクタ(Staticでなければインスタンスのコンストラクタ) static readonly is typically used if the type of the field is not allowed in a const declaration, or when the value is not known at compile time. static readonlyは主に、その変数の型(クラスも?)が定数宣言において許されない時やコンパイルするまで値がわからないような場合に使われる Instance readonly fields are also allowed. インスタンスのreadonlyなフィールドもまた許されている Remember that for reference types, in both cases (static and instance) the readonly modifier only prevents you from assigning a new reference to the field. It specifically does not make immutable the object pointed to by the reference. 参照型においては、Static、インスタンス共に、readonlyはそのフィールドに対して新たな参照を許さないということを覚えておいて欲しい It specifically does not make immutable the object pointed to by the reference. それ(staticなフィールドは)参照によって示されるオブジェクトを不変にはしない class Program { public static readonly Test test = new Test(); static void Main(string[] args) { test.Name = "Program"; test = new Test(); //エラー: Staticのコンストラクタや変数生成の場合以外はstaticなフィールドを割り当てられない } } class Test { public string Name; } On the other hand, if Test were a value type, then assignment to test.Name would be an error. 一方でTestがvalue type(訳注:?)ならtest.Nameはエラーになるだろう。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • 円弧の描画について

    ある参考書の内容について分からない点があります。(VB6です。) '変数と定数の定義 Dim startAngle As Double Dim endAngle As Double Const pi = 3.14152965 '角度の初期値 startAngle = 90 endAngle = 315 '線の色の指定 ForeColor = QBColor(4) '円弧の描画 circle (2000,1500) , 1000, , startAngle * pi / 180, endAngle * pi/180 End Sub 変数の定義で、startAngleとendAngleがDouble型で宣言されているのに、初期値は小数ではなく整数なのはなぜでしょうか。たぶん、初期値は整数だけど、startAngle * pi / 180, endAngle * pi / 180が小数になるからDouble型にしていると思うのですが、このあたりのことを教えていただけますか。

  • javaでC++のdefine文に相当する記述

    毎度、お世話になります。 VC++では、#define文があります。 javaでdefine文に相当する記述について質問します。 javaでは、PIの場合は下記のimport文を記述しますと、 下記の如く、aにPIの値を代入できると思います。 ======================== import static java.lang.Math.PI; static public double a=PI; ======================== Q1) 自分用のpackageを作成して、例えば、この中にPI4即ち、PI*4を設定する方法を   お教え頂けますと大変あり難いです。 以上、宜しくお願いいたします。

    • ベストアンサー
    • Java
  • C#とCでの定数共用に関して

    現在、C(native)でDLL,C#でそのDLLを使ったアプリを開発しています。(Microsoft VisualStudio2008) DLL/アプリともC#あるいはC/C++で記述すれば問題ないのですが、諸般の事情でこのような形態になっていますので、これに関しての意見は無用です。 質問ですが、DLL内の関数の呼び出し時に引数として意味をもった定数を使用する - (たとえばWIN32で使うWM_**等のように) - のですが、この定数値をC#のアプリとでうまく使いまわす手段がないかを探しています。 C#にはCのようにヘッダファイルをインクルードすることができないので、もしやるとすれば、Cのヘッダを何らかのスクリプトで自動変換してC#でそれ用のenumを含むクラス定義のあるソースファイルを自動生成するなどは思いつきますが、スマートな方法ではないですよね。 #C/C++は何十年と使っていますが、C#はごく最近始めました。 なにかもっと簡便な方法はあるのでしょうか。 よろしくお願いいたします。

  • VBでの単純な質問!配列に定数を一発で入れる方法ありますか?

    単純な質問です。 Const B = "0123456789" ←定数 DIM A(10) AS String   ←配列 と言う定義に対して、 A = B と言った方法で、一発でデータをセットして各配列に、 以下のようなデータをセットしようと思っています。 A(0) = 0 A(1) = 1 A(2) = 2 A(3) = 3 A(4) = 4  ・  ・ A(9) = 9 他の言語では再定義などで可能ですが、 VBではいかにしてやるのでしょうか? 定数を個別に切り分けてセットするのが面倒くさいので、ご存知の方いらっしゃれば、宜しくお願いします。

  • 他言語との連係

    c言語と他言語(具体的にはc#など)を連係させるということは可能なのでしょうか? 例えばネットワーク対戦のゲームを作成するとして、ゲームの本体の部分を c言語で書き、ネットワーク関連の部分をc#で記述するといった感じです。 的外れな質問かもしれませんがどなたかご教授お願いします。

  • 桁落ちのプログラムで真の値と計算結果

    #include <stdio.h> const double PI=3.141592653589793; double sum(long m) { double n,term,sum; n=1; sum=0; term= 1.0/ (n*n);/*初項*/ while( n<=m ){ sum+=term; n++; term= 1.0/ (n*n);/*次項の計算*/ } return sum; } /*この計算の答えはπ*/ int main(void) { double s; long m; int i; m=1; for(i=0;i<9;i++){ s=sum(m); printf("%2d m=%10ld sum= %22.16e err= %22.16e \n",i,m,s,s-PI*PI/6); m*=10;/*次は10倍にする*/ } return 0; で真の値と計算結果を調べるにはどうしたらいいのでしょうか?

  • 桁落ちの誤差について

    #include <stdio.h> const double PI=3.141592653589793; double sum(long m) { double n,term,sum; n=1; sum=0; term= 1.0/ (n*n);/*初項*/ while( n<=m ){ sum+=term; n++; term= 1.0/ (n*n);/*次項の計算*/ } return sum; } /*この計算の答えはπ*/ int main(void) { double s; long m; int i; m=1; for(i=0;i<9;i++){ s=sum(m); printf("%2d m=%10ld sum= %22.16e err= %22.16e \n",i,m,s,s-PI*PI/6); m*=10;/*次は10倍にする*/ } return 0; のプログラムで誤差が生じる理由ってなんなんでしょうか?

  • 引数の個数を変えないで変数(定数)を扱う

    別に積分に限らないと思うのですが、積分を例にして質問させていただきます。 次のようなルーチンがあります。 integral( double (*func)(double), double a, double b ); /* a~bまで関数funcを積分する。 */ そこで、簡単に被積分関数を fx=3*x とすれば、 double fx(double x) { return 3*x; } というようにすれば良いですよね。 でも、例えば fx = exp(x-X) とか fx = x*X のような関数を積分したいときはどうすればよいのでしょうか? Xは変数ですが、xにはよらないので積分の中では定数とみなせます。 ループで X=0 のときにfxを積分 X=1 のときにfxを積分 X=2 のときにfxを積分… というようにしたいのですが、 fxの引数をfx(double x, double X) とすると、プロトタイプ宣言もルーチンの中も書き換えなければならなくなりますよね。 さらに fx = x-X + x' などとなったりすると、さらに書き換えなければならなくなり、せっかくの積分のルーチンをうまく使えません。 Xをグローバルで宣言する方法と、 プログラミングの前に、x-X を x' などと置きかえた式を実際に手計算で作る方法を思いついたのですが、 グローバル変数を使うのはあまりよくないし、手計算では簡単な場合しか置換を思いつかなかったりします。 fxの中で X を宣言して、 double fx(double x) { static double X; double y; y = x-X; X++; return y; } という方法も考えたのですが、どうもイマイチ良くないような… こういう場合に、良い方法はありますか? ここには簡単な関数を書きましたが、少し複雑な関数を積分するので。 質問の意図がうまく伝わらなかったらすいません。 書きにくかったです。

  • 角度の計算(C++)

    Theta cos(theta) sin(theta) 0.0    1.00     0.00 .    .     . .    .     . 上のような表示ができるプログラムを書いてます。角度は0度、5度、10度、15度、、、と5度毎に表示させないといけません。表示角度は角度は0-360度までです。 下のように書いてみましたがエラーが出てしまいます。何が問題なんでしょうか? int main(){ const double PI = 3.1415; double r = PI /180; cout<<setw(5)<<"theta"<<setw(13)<<"cos(theta)"<<setw(13)<<"sin(theta)"<<endl; for( int theta=0; theta<=360; <<theta += 5) cout<<setw(5)<<setprecision(1)<<(double)theta <<setw(14)<<setprecision(2)<<sin(theta * r) <<setw(10)<<cos(theta * r)<<endl; return 0; }

  • C言語によるチェビシェフ窓の計算について

    現在、C言語でチェビシェフ窓を計算することを考えてます。 一応、エラーもなく実行できるのですが、中央の値が1になりません。 これで正しいのかどうかもわからないので、どなたか教えていただけないでしょうか。 よろしくお願いいたします。 ///////////////////以下 プログラム ///////////////// #include <stdio.h> #include <math.h> /** * 逆双曲余弦関数の定義 */ double Acosh(double x); /** *チェビシェフ関数の定義 * n:関数の次数 */ double Chev(int n, double x); void main(void) { int i, N=128, k, M=(int)floor((N-1)/2); ///data:入力 w:出力(ウィンドウ係数) ii ,kk インデックスの倍精度型, nn サンプル数の倍精度型 double data[128], w[128], ii, kk, nn; // s :メインローブ対サイドローブの比 double t0, s, u, sum; ////円周率の定義 const double pi=3.1415926; nn=(double)N, s=1000.0; //入力をすべて1に初期化 for(i=0;i<N;i++){data[i]=1.0;} /////チェビシェフ窓の計算ルーチンと出力 t0=cosh((1.0/(nn-1))*Acosh(s)); for(i=0;i<N;i++){ ii=(double)i; for(k=1;k<=M;k++){ kk=(double)k; u=ii-(nn-1)/2.0; if(k==1){ sum=Chev(N-1,t0*cos(kk*pi/nn))*cos(2.0*pi*kk*u/nn); }else{ sum+=Chev(N-1,t0*cos(kk*pi/nn))*cos(2.0*pi*kk*u/nn); } } w[i]=data[i]*(s+2.0*sum)/nn; printf("w[%d]=%4.3f\n",i,w[i]); } } double Acosh(double x) { double x2=x*x; return log(x+sqrt(x2-1)); } double Chev(int n, double x) { if(fabs(x)<=1){ return cos((double)n*acos(x)); }else{ return cosh((double)n*Acosh(x)); } } /////////////// ここまで /////////////////// //////////////////以下出力結果///////////// w[0]=0.628 w[1]=0.285 w[2]=0.348 w[3]=0.419 w[4]=0.499 w[5]=0.588 w[6]=0.686 w[7]=0.795 w[8]=0.914 w[9]=1.044 [中略] w[50]=14.268 w[51]=14.559 w[52]=14.832 w[53]=15.085 w[54]=15.320 w[55]=15.533 w[56]=15.725 w[57]=15.895 w[58]=16.041 w[59]=16.164 w[60]=16.264 w[61]=16.338 w[62]=16.388 w[63]=16.413<-中央値 w[64]=16.413<-中央値 w[65]=16.388 [中略] w[121]=0.686 w[122]=0.588 w[123]=0.499 w[124]=0.419 w[125]=0.348 w[126]=0.285 w[127]=0.628