字符串引用相等性检查是否保证是静态的?

时间:2013-05-19 05:45:12

标签: c# string

我有一个带有此签名的函数:

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" );
    }
}

我想知道这种技术,使用空字符串和对象引用相等是否总是安全的,特别是对于字符串实习。

2 个答案:

答案 0 :(得分:3)

Antimony is right about the reasons this will not work

我建议你为参数定义一个类型。我们称之为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);
    }

这是从字符串到ExampleArgument的隐式转换运算符。

DoSomething(ExampleArgument.FirstKnownValue);
DoSomething(new ExampleArgument("hello"));
DoSomething("hello"); // equivalent to previous line, uses implicit conversion operator

答案 1 :(得分:1)

不,这不安全。事实上,这将永远不会奏效。字符串文字得到实习,因此两个特殊值都具有相同的引用。大多数编译器也会实习编译时间常量字符串,你总是可以手动实习字符串。

不幸的是,如果你想接受任何有效的字符串,你需要一些其他方法来传递额外的信息。即使像这样的黑客工作,这也是一个坏主意,因为它违反了正常的字符串相等语义。

以下是我能想到的可能性

  • 如果您只有一个特殊值,则可以使用null
  • 采用更广泛的类型,例如Object作为输入
  • 采取两个参数
  • 制作单独的功能