根据this answer,CSV::Converters[:mytime] = lambda do |s|
DateTime.parse(s.tr(?E, ?T)) rescue s
end
CSV.parse("20150515000019", converters: :mytime)
# [[#<DateTime: 2015-05-15T00:00:19+00:00 ((2457158j,19s,0n),+0s,2299161j)>]]
和""
略有不同,因为string.Empty
会创建一个对象,而""
则不会。那个答案对这个问题的投票最多。
然而,this answer表示没有区别。这也是最近的答案。
所以这是在2010年。这是真的吗? string.Empty
和string.Empty
完全不同,甚至是略有不同吗?
编辑:这个问题是对相关问题的更新,因为我发现令人困惑的是,尽管对此事进行了一些辩论,但没有提出任何现代答案。
答案 0 :(得分:6)
语言规范(C#4.0)实际上对此主题保持沉默。
根据CLR通过C#,它完全取决于CLR而不是C#编译器。来自p的相关引用。 341:
即使程序集指定了此属性/标志[CompilationRelaxations.NoStringInterning],CLR也可以选择实习字符串,但您不应指望这一点。实际上,除非你自己编写的代码明确地调用了String的Intern方法,否则你真的不应该编写依赖于字符串实例的代码。
因此使用""
可能会也可能不会创建新的字符串对象。这取决于所使用的CLR(版本)。并且编译器也可能折叠常量,在这种情况下""
每个 assembly 编译单元将花费1个对象,而不是每次出现。
这些都不会对内存使用或速度产生任何相关影响,但明确的指导原则应该是避免使用ReferenceEquals(s1, "")
和ReferenceEquals(s1, String.Empty)
。
当然,Object.Equals(s1, s2)
和s1 == s2
始终可以正常使用字符串。
答案 1 :(得分:0)
您可以在String.Empty中正确阅读,此字段的值(String.Empty
)是零长度字符串,""
。
您可以通过小测试来测试它们是否引用相同的字符串。
void main()
{
String first = "";
String second = String.empty;
bool test = Object.ReferenceEquals(first, second);
}
Test将返回true,这意味着它们引用同一个对象。
另一个细微差别是,评估""
比String.empty
稍微更优化和有效。
修改强>
static void Main ( string[] args )
{
string s1 = "MyTest";
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = String.Intern(s2);
Console.WriteLine((Object)s2 == (Object)s1); // Different references.
Console.WriteLine((Object)s3 == (Object)s1); // The same reference.
Console.WriteLine();
s1 = "";
s2 = new StringBuilder().Append("").ToString();
s3 = String.Empty;
string s4 = String.Intern(s2);
Console.WriteLine((Object)s2 == (Object)s1); // The same reference.
Console.WriteLine((Object)s3 == (Object)s1); // The same reference.
Console.WriteLine((Object)s4 == (Object)s1); // The same reference.
Console.WriteLine((Object)s4 == (Object)s2); // The same reference.
}
很明显告诉实习生字符串文字已被实习。当stringbuilder
创建一个具有相同对象的新String对象时,它不会被实现,并且对该对象的引用也不相同。但是,当我们String.Intern(s2)
时,该方法会返回分配给s1
的相同引用,然后将引用分配给s3
。
<强>思想强>
为什么然后,四个案例都返回true。我知道字符串文字""
是固定的,但为什么不使用Stringbuilder
将""
附加到与""
相同的新字符串对象,即使从技术上来说也是如此是一个没有实习的新对象。
答案 2 :(得分:-1)
由于有些人已经评论了CLR做什么/不做什么以及对象.RefereceEquals,我将提供两个以上的输入数据。
表现明智,没有任何重大差异。我用这段代码来测试它:
示例代码:
public class StringsTest
{
private int i, maxValue = 500000000;
string myString = "test";
public long CompareToEmptyQuotes()
{
Stopwatch sw = Stopwatch.StartNew();
sw.Start();
for (i = 0; i < maxValue; i++)
{
if (myString == "")
{
;
}
}
sw.Stop();
Debug.WriteLine("Elpased Time: {0}", sw.ElapsedMilliseconds);
return sw.ElapsedMilliseconds;
}
public long CompareToEmptyString()
{
Stopwatch sw = Stopwatch.StartNew();
sw.Start();
for (i = 0; i < maxValue; i++)
{
if (myString == string.Empty)
{
;
}
}
sw.Stop();
Debug.WriteLine("Elpased Time: {0}", sw.ElapsedMilliseconds);
return sw.ElapsedMilliseconds;
}
}
关于生成的代码,这就是MSIL的样子:
使用&#34;&#34;生成:IL_001e:ldstr&#34;&#34;
使用string.Empty生成:IL_001e:ldsfld string [mscorlib] System.String :: Empty
这个问题here扩展了ldstr和ldsfld之间的差异(或相等)。