是保证为静态的字符串引用相等性检查
本文关键字:引用 检查 字符串 静态 | 更新日期: 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作为输入
- 取两个参数
- 创建一个单独的函数