57

同僚がC#で次の構造を作成しました(サンプルコードは簡略化されています)。彼の目標は、コードの残りの部分で事前定義されたすべての文字列の表記を短くすることでした。

public struct PredefinedStrings
{
    public const string VeryLongName = "Very Long Name";
    public const string AnotherVeryLongName = "Another Very Long Name";
    public const string TheLastVeryLongName = "The Last Very Long Name";
}

public static void MethodThatUsesTheNames()
{
    Console.WriteLine(PredefinedStrings.VeryLongName);
    Console.WriteLine(PredefinedStrings.AnotherVeryLongName);
    Console.WriteLine(PredefinedStrings.TheLastVeryLongName);
}

彼にとってはうまくいくように見えますが、彼が構造体の代わりに静的クラスを使用すべきだったのか、それともこれを実現するためのよりエレガントな方法があるのか​​疑問に思うのは止められません。

これを行うための好ましい方法は何でしょうか?その理由も説明してください。

4

13 に答える 13

53

このstructソリューションでは、他のコードの実行を停止することはできません。これは悪いことは何もしnew PredefinedStrings()ませんが、意味的に混乱させるものです。静的クラスを使用すると、コンパイラは作成を禁止します。そして言うまでもなく、静的クラスはフレームワークで定数を提供するための好ましい方法です。

追加するために編集して、私は証拠のない第二の部分を言いました-それ以来、私は検索し、合理的に迅速に見つけましSystem.Net.Mime.DispositionTypeNamesSystem.Net.WebRequestMethods.Http

于 2010-02-08T16:44:12.767 に答える
32

主に国際化の理由から、文字列はすべてリソースファイルにあり、コードに埋め込まれていない方がいいと思います。これは、プロパティメンバーとして値を使用して静的クラスを介してアクセスできます。

于 2010-02-08T16:46:12.323 に答える
26

と以外に、static class定数文字列にファイルをstruct使用することを検討してみませんか? resourceこれらは として非常に簡単にアクセスできSomeNamespace.ResourceName.KeyName、プロジェクト内の場所に応じて、必要に応じて再コンパイルせずに外部で管理できます...

于 2010-02-08T16:47:57.140 に答える
12

単純な経験則: 他に選択肢がなくなるまで構造体を使用しないでください。

定数にはいくつかの欠点があります。

  • 単純な型 (文字列、数値など) のみを使用できます。
  • 定数は参照アセンブリに挿入されます。定数を使用するアセンブリを再コンパイルし、定数を使用するアセンブリを再コンパイルしないと、問題が発生します

私はあなたのコードを次のように書きます(リファクタリングの名前変更にも注意してください):

public static class KnownNames
{
    public static readonly string VeryLong = "Very Long Name";
    public static readonly string AnotherVeryLong = "Another Very Long Name";
    public static readonly string TheLastVeryLong = "The Last Very Long Name";
}
于 2010-02-08T17:30:42.170 に答える
6

このコードには機能的に問題はありません。しかし、スタイル的には、静的クラスの方が優れていることに同意します。静的クラスは、型の目的が静的/定数データのみを保持することであることを宣言します。

于 2010-02-08T16:45:22.793 に答える
6

リソース ファイル (.resx) を探しているようです。このような文字列を格納するのに適切な場所であり、文字列を .resx に抽象化すると、将来的にアプリケーションをローカライズしやすくなります。詳細については、 http: //msdn.microsoft.com/en-us/library/1ztca10y.aspx の MSDN ページを参照してください。

于 2010-02-08T16:51:17.477 に答える
5

ETA: Dennis19901に感謝します: これらの文字列はconstであるため、実際にはスペースを占有しません。はstruct1 バイトのみを消費します。

古い情報: 構造体のサイズは約 16 バイトであるという推奨事項を忘れないでください。32 ビット システムの場合、4 つの System.String 参照があります。文字列の数が増える場合は、静的クラスを使用したほうがよいと思います。

于 2010-02-08T17:04:13.910 に答える
3

静的クラスは、最も標準的で期待されるため、最適な方法のようです。struct/const バージョンの方が速いかもしれないと思っていましたが、いくつかのテストの後、そうではありませんでした。

これは、length、compare、concat、copy、indexOf、および Substring を含む簡単なテストの結果です。デバッガーが接続されていないリリースで.Net 4.0で実行されました。

                                          .Net 3.0  .Net 4.0
static class with static read-only string:  0.217   0.364  seconds
static class with const            string:  0.211   0.361  seconds
struct       with static read-only string:  0.211   0.372  seconds
struct       with const            string:  0.214   0.371  seconds
Properties.Resources               string:  1.173   1.268  seconds

速度が遅いリソース ファイルを使用する場合を除いて、それらはすべてほぼ同じパフォーマンスでした。Properties.Resources は低速で​​すが、実行可能ファイルに保存されないため、場合によってはその方が適切な場合があります。したがって、私の意見では、「静的クラス」または文字列を格納する Properties.Resources のいずれかを使用してください。

于 2014-12-27T20:58:32.407 に答える
2

この回答で詳述されている特定の基準を満たさない限り、構造体は通常回避されます。

あなたの同僚は値を格納するためにそれを使用していないので、構造体ではなくクラスを使用する必要があります。

于 2015-06-26T21:19:59.987 に答える
1

静的の方が優れていると思います。これが私の理由です。このコードが何らかのライブラリに存在し、別のコードがこのライブラリを使用する場合、定数フィールドの値が変更された場合、このライブラリを再コンパイルする必要があるだけでなく (duh)、これを使用するコードを再コンパイルする必要があります図書館も。その理由は、コンパイルは定数値を参照する場所に挿入するためです。ただし、 static を使用すると、ではなくフィールドを参照しているため、この問題は発生しません。

于 2010-02-08T16:48:28.557 に答える
0

この目的のための私の練習では、を使用しますDictionary<enumNameType, string>。ここで、enumNameTypeは、(あなたの場合)持つことができるさまざまなタイプの名前です...このディクショナリは静的クラスにラップされてキャッシュされます-初めて使用するときに作成し、同じオブジェクトを返します...

これがあなたにも役立つことを願っています!

于 2010-02-08T16:43:59.327 に答える
0

定数にも構造体を使用しますが、パブリック API ではなく内部使用のみです。列挙型も構造体に変換されるので自然な感じです。

于 2010-02-08T16:49:01.803 に答える
0

定数であることを意図した新しいオブジェクトを作成することが許可されているという単純な事実は、悪い習慣の明確な証拠です (通常)。「通常」と言ったのは、理由は不明ですが、.NET がこの概念を時々利用するためです。

もちろん、次のようなことはいつでもできます。

public class Foo
{
    public struct Bar
    {
        public static double A = 100;

        public Bar(double a)
        {
            A = a;
        }
    }
}

Bar;の作成を技術的に正当化するものはどれですか。ただし、定数Barが同じになるという保証はなく (シングルスレッド環境であっても)、最終的にはほとんど役に立ちません。

于 2017-01-26T18:19:25.013 に答える