2

パラメータに定義済みの値を設定するにはどうすればよいですか? たとえば、次の機能があります。

int functionA(string parameterA) {}

ここで、この関数を呼び出して parameterA の値を入力すると、定義した値セットに値が含まれるようになります。たとえば、定義された値セットは次のとおりです。

string[] definedParameterA = { "Hello World", "stackoverflow" };

入力する parameterA の値は、「Hello World」または「stackoverflow」でなければなりません。

4

3 に答える 3

4

本当に文字列にしたい場合は、メソッドの開始時に検証するだけです。

private static readonly String[] ValidValues = {"Hello World", "stackoverflow"};

public void DoSomething(string text)
{
    if (!ValidValues.Contains(text))
    {
        throw new ArgumentException("Invalid value: " + text, "text");
    }
    // Carry on
}

ただし、代わりに列挙型の使用を検討することもできます。列挙値が定義されていることを検証する必要がありますが、呼び出し元が正しく取得するのが簡単になります。

public enum Message
{
    HelloWorld,
    StackOverflow
}

public void DoSomething(Message message)
{
    if (!Enum.IsDefined(typeof(Enum), message))
    {
        throw new ArgumentException("Invalid value: " + message, "message");
    }
    // Carry on
}

もちろん、必要に応じて、列挙値から他の場所の文字列へのマッピングを行うことができます。

上記のコードはmessage、すべての呼び出しでボックス化されることに注意してください。本当に必要な場合は、 Unconstrained Melodyプロジェクトを使用してそれを回避する (そしてよりタイプセーフにする) ことができますが、このボクシングが実際に問題であることを証明するまでは、おそらく価値がありません。コードは次のようになります。

public void DoSomething(Message message)
{
    if (!message.IsNamedValue()) // Extension method
    {
        throw new ArgumentException("Invalid value: " + message, "message");
    }
    // Carry on
}
于 2013-02-17T08:11:50.113 に答える
0

たぶん、静的クラスが役立ちます。

public static class MyValidParameters
{
    public static const string HelloWorld = "Hello World";
    public static const string Stackoverflow = "stackoverflow";
    //
}

そのため、任意の型の複雑なパラメーター (文字列だけでなく) を持つことができ、それらをさまざまな静的クラスで管理できます。

于 2013-02-17T08:19:01.263 に答える
0

ジョン・スキートの答えを最も一般的な言葉で言い換えたいと思います:

文字列を使用しています。文字列は、 からシェイクスピアの全作品に至るnullまで、可能な値の事実上無制限のスペクトルを含むことができる無制限の型です。""少数の可能な値しか期待していない場合は、無制限のデータ型は適切な選択ではない可能性があります。おそらく、代わりに境界のあるデータ型に置き換えることができますか?

John Skeet が示すように、システムに組み込まれている最も単純な境界付きデータ型は Enum です。それらは可能な値の閉じたセットを提供します。したがって、入力を取得し、それを値のリストにマップし、それをこれから使用します。ただし、いくつかの複雑な問題があります。1 つ目は、John Skeet が言及したパフォーマンス ペナルティの可能性です。2 つ目は、すべての文字列を Enum 値として表現できるわけではないということです。たとえば、「He​​llo World」は有効な C# 識別子ではないため、列挙型にマップするのは困難です。

これは、 enum 値を[Description("Hello world")]or[DisplayName("Hello world")]属性で装飾し、リフレクションを使用して一致させることで実行できますが、それには独自のパフォーマンス上のペナルティがあります。この場合、文字列を列挙値にマップするための何らかの静的ユーティリティを用意することを検討できます。

于 2013-02-17T08:46:05.797 に答える