在我上次的c#访问中,
我被要求证明C#字符串的不变性,我知道c#字符串的不变性是什么意思,但是有可能通过代码证明c#字符串的不变性吗?我可以有一个示例代码片段吗? 在此先感谢如何证明C#中字符串的不可变性?
回答
我能证明string
是不一成不变的。所有我需要做的是显示一些代码,变异一个string
,像这样:
using System;
using System.Runtime.InteropServices;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
const string test = "ABCDEF"; // Strings are immutable, right?
char[] chars = new StringToChar {str = test}.chr;
chars[0] = 'X';
// On an x32 release or debug build or on an x64 debug build,
// the following prints "XBCDEF".
// On an x64 release build, it prints "ABXDEF".
// In both cases, we have changed the contents of 'test' without using
// any 'unsafe' code...
Console.WriteLine(test);
// The following line is even more disturbing, since the constant
// string "ABCDEF" has been mutated too (because the interned 'constant' string was mutated).
Console.WriteLine("ABCDEF");
}
}
[StructLayout(LayoutKind.Explicit)]
public struct StringToChar
{
[FieldOffset(0)] public string str;
[FieldOffset(0)] public char[] chr;
}
}
现在,这是否应该考虑在C#中的错误是另一回事。 :) (答案可能是FieldOffset
应该被认为是unsafe
- 上面的代码是据称safe
,因此string
不应该mutatable)
另外,我觉得你可以合法地认为string
是不可变的精神,即使在假定的安全代码中存在违反其不可变性的愚蠢的边缘案例。
,将切换为upvote这是如何证明的字符串是可变的?这不是像'stringVariable + =“某些字符串”;'这样的概念吗?当你做了最后一行代码时,编译器不能简单地连接'stringVariable'的当前值和你提供的新字符串;相反,它会创建一个新的字符串对象,并将其设置为等于新的连接字符串。 –
你证明字符串为可变对象,这是如何证明字符串的不变性,@ shamseer k smr回答正确答案 – samurai
'FieldOffset'肯定应该是'unsafe',而不仅仅是因为这个例子。很好的例子。 –
是的,可以使用ObjectIDGenerator
类证明c#字符串的不变性。
以下的答案必须从dotmob文章在C#中采取String Vs Stringbuilder
其实ObjectIDGenerator将返回情况下,我们在我们programs.With创建此类的帮助下,我们可以检查一个唯一的整数值是否创造了新的实例,或者不是为字符串和StringBuilder的各种操作。考虑下面的程序
using System;
using System.Text;
using System.Runtime.Serialization;
class Program
{
static void Main(string[] args)
{
ObjectIDGenerator idGenerator = new ObjectIDGenerator();
bool blStatus = new bool();
//just ignore this blStatus Now.
String str = "My first string was ";
Console.WriteLine("str = {0}", str);
Console.WriteLine("Instance Id : {0}", idGenerator.GetId(str, out blStatus));
//here blStatus get True for new instace otherwise it will be false
Console.WriteLine("this instance is new : {0}\n", blStatus);
str += "Hello World";
Console.WriteLine("str = {0}", str);
Console.WriteLine("Instance Id : {0}", idGenerator.GetId(str, out blStatus));
Console.WriteLine("this instance is new : {0}\n", blStatus);
//Now str="My first string was Hello World"
StringBuilder sbr = new StringBuilder("My Favourate Programming Font is ");
Console.WriteLine("sbr = {0}", sbr);
Console.WriteLine("Instance Id : {0}", idGenerator.GetId(sbr, out blStatus));
Console.WriteLine("this instance is new : {0}\n", blStatus);
sbr.Append("Inconsolata");
Console.WriteLine("sbr = {0}", sbr);
Console.WriteLine("Instance Id : {0}", idGenerator.GetId(sbr, out blStatus));
Console.WriteLine("this instance is new : {0}\n", blStatus);
//Now sbr="My Favourate Programming Font is Inconsolata"
Console.ReadKey();
}
}
当str与“Hello World”串联在一起时,字符串的实例ID从1变为2,同时追加操作后sbr的实例ID与3保持相同。这告诉所有关于易变性和不变性。 blStatus变量指示实例是否是新的。
你可以找到关于从主题完整的文章:http://dotnetmob.com/csharp-article/difference-string-stringbuilder-c/
让我先检查它,如果它是正确的,我会接受你的回答 –
这只能证明你正在测试的操作符和方法会创建新的字符串实例。它并不能证明字符串总是不变的。请参阅J下面的问题的评论,为什么不能用数学/科学的证明来证明这一点。 –
感谢文章 – samurai
一个简单的例子:
string str = "test";string str2 = str;Console.WriteLine(str2);
//输出:测试
str = "DDD";Console.WriteLine(str2);
//输出:测试
试试这个代码,如果字符串是可变的,“ str2“应该是”DDD“。
- 1. “证明”该字符串是在C#不可改变
- 2. 字符串不可变性
- 3. c + +中可变的内存声明一个字符串字面
- 4. Ruby字符串可变性
- 5. C++字符串文字的安全性和可靠性如何?
- 6. WP7中的可变字符串C#/ XNA?
- 7. Objective-C如何处理不可变字符串的内存
- 8. C++字符串变量声明
- 9. Java:如何“改变”一个字符串,尽管字符串的不变性?
- 10. 字符串不变性
- 11. Java字符串如何不可变增加安全性?
- 12. 字符串不变性的安全性
- 13. 如何声明可变数量的索引字符串?
- 14. coq中的字符串证明
- 15. 如何添加到目标c中的可变字符串?
- 16. Python中的字符串不可改变
- 17. 在Java中不可变的字符串?
- 18. C++ - 如何查找字符串中的(变量)字符?
- 19. 字符串变得不明确
- 20. c中的字符串数组声明
- 21. 托管C++中的字符串声明
- 22. 程序在C中反转字符串而不声明字符[]
- 23. C字符串声明
- 24. C++字符串声明
- 25. MS C#实现字符串首先检查不可变基字符串的ReferenceEquals?
- 26. 混乱的字符串不变性
- 27. 如何在c#中使用xml中的字符串变量作为字符串?
- 28. 如何在C#中表示(字符串,字符串[],字符串[])#
- 29. 验证属性中的空字符串
- 30. 如何在C#中字串字符串
检查两个字符串对象的对象引用,它们将是相同的。 – Marshal
编写一个连接字符串的循环,然后观察GC发疯,并且您的应用程序像疯了一样烧毁内存? – Nasreddine
你不能 - 实际上,你确实可以证明你*可以*使用不安全的代码对一个字符串进行变异。你可以做的最好的事情是指向那些承诺字符串是不可变的规范(在CLR安全代码的上下文中)。如果你的工作是编程,你必须习惯于信任语言规范 - 如果语言不符合规范说明的话,这是编译器团队修复的一个错误。你可以演示一个字符串没有变异的例子,但它没有证明任何东西。有可能是构建失败的地方。直到你找到一个,你必须简单地相信规范。 –