2

特定の長さの文字列のみを許可するC#値型を宣言したいと思います。上記の長さは、コンパイル時に検証する必要があります。これはDelphiで次のように実行できます。

type
  TString10 = string[10];

そして、私が言ったtyoeを次のように使用する場合:

var
  sTen : TString10;

sTen := '0123456789A';   //This generates a compile time error

私が理解しているように、固定長のC#で文字列型を宣言することはできません。私が見たさまざまなソリューションでは、C#のコンパイル時チェックが提供されていません。私は自分のC#値型構造体を宣言する準備ができているので、これは私が達成できるもの.Format()ですか?

すべてのヘルプとポインタは大歓迎です。

PS。文字列の長さの割り当てのコンパイル時チェックを本当に実現したいので、「Why are you ....?」は使用しないでください。

4

5 に答える 5

5

System.String に次のコンストラクター オーバーロードがあるとします。

public String(char[] value)

次のように独自の値の型を作成できます。

public struct FixedLengthString
{
    private readonly string s;

    public FixedLengthString(char c1, char c2, char c3)
    {
        this.s = new string(new [] { c1, c2, c3 });
    }
}

この特定の例では、次のように初期化された、正確に 3 文字の文字列が得られます。

var fls = new FixedLengthString('f', 'o', 'o');
于 2011-08-05T07:12:22.197 に答える
3

パズルがあります。TString10が既に C# に存在し、長すぎる文字列を割り当てるとコンパイル時にエラーが発生すると仮定しましょう。

string stringWithUnknownLength = "".PadLeft(new Random().Next(0, 100));

TString10 foo = stringWithUnknownLength;

ここでコンパイル時エラーを発生させる必要がありますか? もしそうなら、コンパイラはいつそれを上げるべきかをどのように知るのでしょうか?

ご覧のとおり、コンパイル時のチェックの可能性は限られています。特定の文字列定数TString10変数に代入する場合など、コンパイラが簡単に確認できることがいくつかあります。しかし、検証がおそらく複雑なプログラム ロジック、I/O、または乱数 (上記の例のように) に依存するケースは非常に多くあります。これらすべてのケースで、コンパイル時のチェックは不可能です。


私は当初、コード コントラクトstringの静的チェック機能と組み合わせた、ラッパー クラスの組み合わせを提案するつもりでした。ただし、そのアプローチには同じ根本的な問題があります。とにかく、完全を期すために:

using System.Diagnostics.Contracts;

class TString10
{
    private string value;

    …

    public static implicit operator TString10(string str)
    {
        Contract.Requires(str.Length <= 10);
        return new TString10 { value = str };
    }

    public static implicit operator string(TString10 str10)
    {
        Contract.Ensures(Contract.Result<string>().Length <= 10);
        return str10.value;
    }
}
于 2011-08-05T07:51:45.577 に答える
3

Spec#を使用すると、文字列の長さなど、コンパイル時にさまざまなことを制限できます。

于 2011-08-05T07:12:01.223 に答える