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

本文关键字:引用 检查 字符串 静态 | 更新日期: 2023-09-27 18:14:29

我有一个这样签名的函数:

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

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

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

锑是正确的原因,这将不起作用。

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

不,这不安全。事实上,这是行不通的。字符串字面值被保留,因此两个特殊值将具有相同的引用。大多数编译器也会编译时间常量字符串,你也可以手动编译字符串。

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

这些是我能想到的可能性

  • 如果你只有一个特殊值,你可以使用null
  • 采用更广泛的类型,如Object作为输入
  • 取两个参数
  • 创建一个单独的函数