我有一个带有此签名的函数:
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" );
}
}
我想知道这种技术,使用空字符串和对象引用相等是否总是安全的,特别是对于字符串实习。
答案 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)
不,这不安全。事实上,这将永远不会奏效。字符串文字得到实习,因此两个特殊值都具有相同的引用。大多数编译器也会实习编译时间常量字符串,你总是可以手动实习字符串。
不幸的是,如果你想接受任何有效的字符串,你需要一些其他方法来传递额外的信息。即使像这样的黑客工作,这也是一个坏主意,因为它违反了正常的字符串相等语义。
以下是我能想到的可能性