1

私はこの署名を持つ関数を持っています:

public void DoSomething(String name);

私のアプリケーションでは、文字列nameは特別です。任意の文字列または特別な既知の値のいずれかです。空でない文字列値はすべて有効な入力であるため、次のように、空の文字列でオブジェクト参照の等価性を使用する必要があることを意味します。

public class Foo {

    public const String SpecialValue1 = "";
    public const String SpecialValue2 = "";

    public void DoSomething(String name) {

        if( Object.ReferenceEquals( name, SpecialValue1 ) ) {



        } else if( Object.ReferenceEquals( name, SpecialValue2 ) {


        } else {

        }
    }

    public void UsageExample() {

        DoSomething( SpecialValue1 );
        DoSomething( "some arbitrary value" );
    }
}

特に文字列のインターンに関して、空の文字列とオブジェクト参照の等価性を使用するこの手法が常に安全かどうかを知りたいです。

4

2 に答える 2

3

これがうまくいかない理由についてアンチモンは正しい

引数の型を定義することをお勧めします。と呼びましょうExampleArgument

public class ExampleArgument
{
    private readonly int _knownValue;
    private readonly string _arbitraryValue;

    public ExampleArgument(string arbitraryValue)
    {
        _arbitraryValue = arbitraryValue;
        _knownValue = 0;
    }

    private ExampleArgument(int knownValue)
    {
        _knownValue = knownValue;
        _arbitraryValue = null;
    }

    public static readonly ExampleArgument FirstKnownValue = new ExampleArgument(1);
    public static readonly ExampleArgument SecondKnownValue = new ExampleArgument(2);

    // obvious Equals and GetHashCode overloads

    // possibly other useful methods that depend on the application
}

ああ、あなたの例で呼び出し構文が本当に必要な場合は、次を追加できます。

    public static implicit operator ExampleArgument(string arbitraryValue)
    {
        return new ExampleArgument(arbitraryValue);
    }

string から への暗黙的な変換演算子ExampleArgumentです。

DoSomething(ExampleArgument.FirstKnownValue);
DoSomething(new ExampleArgument("hello"));
DoSomething("hello"); // equivalent to previous line, uses implicit conversion operator
于 2013-05-19T06:05:24.150 に答える
1

いいえ、これは安全ではありません。実際、これは決してうまくいきません。文字列リテラルはインターンされるため、両方の特別な値が同じ参照を持つことになります。ほとんどのコンパイラはコンパイル時の定数文字列もインターンし、いつでも文字列を手動でインターンできます。

残念ながら、有効な文字列を受け入れたい場合は、別の方法で追加情報を渡す必要があります。そして、このようなハックが機能したとしても、それは通常の文字列等価セマンティクスに違反するため、悪い考えです。

ここに私が考えることができる可能性があります

  • 特別な値が 1 つしかない場合は、null を使用できます
  • Object などのより広いタイプを入力として受け取る
  • 2 つのパラメーターを取る
  • 別の機能を作る
于 2013-05-19T05:49:39.797 に答える