5

OK、つまり、可能な状態コードの数が少ない char(1) 型のデータベース フィールドがあります (たとえば、「F」= 失敗、「U」= 不明など)。これらの状態に対応する C# 列挙型クラスが必要です。できます:

public enum StatusCode : byte {
    Unknown = (byte) 'U',
    Failure = (byte) 'F',
    // etc.
}

ここまでは順調ですね。しかし、データベースから返された DataTable では、列の値は System.Data.SqlTypes.SqlString インスタンスです。C# 文字列 (または C# char) から C# バイトへの変換には明らかにいくつかの問題があります (C# char は実際には UTF-16 コードポイントであるため)。しかし、この場合、値が小さなセットに制限されていることがわかっており、このセット外の値が渡された場合、コードは例外をスローする必要があります。

それを念頭に置いて、これを行う最良の方法は何ですか?SqlString からバイトにキャストしても安全ですか? Convert.ToByte() の方が良いでしょうか? 単純にスイッチ/ケース構成を使用して、値を列挙型にクロスウォークする方がよいでしょうか?

正しい結果を得るためだけでなく、コードを明確にするためにも、これを行うための「最良の」方法を探しています。次のような定数を使用することもできると思います

public const char UnknownStatus = 'U';
public const char FailureStatus = 'F';

しかし、可能であれば列挙型を使用したいと思います。何かご意見は?

編集:これで何をしたいのかを明確にするために、コード全体でこれらの値を頻繁に使用することを期待しています。たとえば、次のようなことができるようになりたいです。

public void DoSomething(StatusCode currentStatus) {
    if(currentStatus == StatusCode.Failure) {
        throw new SomeException();
    }

    switch(currentStatus) {
        case StatusCode.Unknown:
            // do something
            break;
    }
}

などなど。特に次のようなことは避けたいです。

public void DoSomething(char currentStatus) {
    if(currentStatus == 'F') {
        // do something
    }
}

この場合、至る所で「マジックナンバー」に相当するものを使用しているためです。特に、これにより、他の状態フラグシステムへの移行が事実上不可能になります。それは理にかなっていますか?

4

7 に答える 7

5

たぶん「一定の」オブジェクト?

public sealed class StatusCode {
    private char value;

    public static readonly StatusCode Unknown = new StatusCode('U');
    public static readonly StatusCode Failure = new StatusCode('F');

    private StatusCode(char v) {
        value = v;
    }

    public override string ToString() {
        return value.ToString();
    }

}

次に、コードの後半で、列挙型のように使用できますStatusCode.Unknown。受信した値をStatusCodeのオブジェクトに「解析」するための内部メソッドを提供することもできます。

于 2009-07-24T21:40:13.387 に答える
1

編集にスキップこれを試しましたか(チェックしてコメントしたので機能しません):

public enum StatusCode : char
{
    Failure = 'F',
    Unknown = 'U',
    ...
}

編集-正しい解決策
またはこれ(おそらく構造体で試してみてください):

public sealed class StatusCode
{
    public static readonly char Failure = 'F';
    public static readonly char Unknown = 'U';
    ...
    public char Value { get; set; }
}

指定したコードは次のように機能します。

public void DoSomething(StatusCode currentStatus) {
    if(currentStatus.Value == StatusCode.Failure) {
        throw new SomeException();
    }

    switch(currentStatus.Value) {
        case StatusCode.Unknown:
            // do something
            break;
    }
}

プロパティを使用したくない場合は、と型Valueの間に暗黙の等式演算子をいつでも実装できます。その場合、コードは少し変更されません。StatusCodechar

于 2009-07-24T21:24:37.317 に答える
0

整数の主キーを含むStatusCodeというテーブルがある場合は、それを識別子として使用するだけでなく、ロジックにフックすることもできます。その場合、列挙型を使用するのが最適です。これがあなたにとって実行可能かどうかはわかりませんが。

于 2009-07-24T21:24:56.957 に答える
0

1つのオプションは、次のように、データベース内の値と同じ名前で列挙型を設定することです。

enum StatusCode
{
    /// <summary>Unknown</summary>
    U = 0,
    /// <summary>Failure</summary>
    F,
    /// <summary>Etc</summary>
    E
}

次に、静的メソッドを使用して、char値を列挙値に変換します

    private StatusCode CharToEnum(string statusCodeChar)
    {
        foreach (FieldInfo fi in typeof(StatusCode).GetFields())
        {
            if (fi.Name == statusCodeChar) return (StatusCode)fi.GetValue(null);
        }

        return StatusCode.U;
    }
于 2009-07-24T21:40:24.900 に答える
0

短くて甘い私の男..あなたが必要とするすべてを行います. 可能な状態に内部値を割り当てる必要がないため、列挙型を使用する必要はありません。状態の値は既にわかっています。

public sealed class StatusCode
{
    public const string Unknown= "U";
    public const string Failure= "F";
    public const string Success= "S";
}
于 2009-08-19T22:40:16.703 に答える
0

このようなものはあなたのために働くでしょうか?

public Enum StatusCode : int{
   [StringValue("U")]
   Unknown =0,
   [StringValue["F"]
   Failuer=1
}
于 2009-07-24T21:21:53.517 に答える
0

.NET 2.0 以降を使用している場合は、汎用辞書を使用してこれを実装できます。

Dictionary<char,string> statusCode = new Dictionary<char,string>();
statusCode.Add('U', "Unknown");
statusCode.Add('F', "Failure");

または代わりに:

Dictionary<char,StatusCode> statusCode = new Dictionary<char,StatusCode>();
statusCode.Add('U', StatusCode.Unknown);
statusCode.Add('F', StatusCode.Failure);

次のように、特定のコードの文字列表現にアクセスできます。

string value = statusCode['A'];

また

StatusCode myCode = statusCode['A'];

等々。データベースの値、または何らかの構成ファイルなどからその辞書を埋める必要があります。

マルク

于 2009-07-24T21:18:46.050 に答える