在将 .net Framework 应用程序移植到 .net core 应用程序时,可以使用
String.Copy
来复制字符串。但看起来这个方法已从 .net core 中删除,那么如何在 .net core 应用程序中复制字符串,结果,它也不存在于 uwp 中。 .net core 中的赋值 string b = a;
与 .netframework 中的赋值有什么不同吗?
此代码中使用了副本:
public DataDictionary(DataDictionary src)
:this()
{
this.Messages = src.Messages;
this.FieldsByName = src.FieldsByName;
this.FieldsByTag = src.FieldsByTag;
if (null != src.MajorVersion)
this.MajorVersion = string.Copy(src.MajorVersion);
if (null != src.MinorVersion)
this.MinorVersion = string.Copy(src.MinorVersion);
if (null != src.Version)
this.Version = string.Copy(src.Version);
}
这不像
string.Copy()
那么优雅,但是如果您出于某种原因不希望引用相等,请考虑使用:
string copiedString = new string(stringToCopy);
字符串的赋值与创建副本不同。
a = b
只是将两个变量的引用设置为同一内存段。 string.Copy
实际上复制了字符串,因此引用不再相同。
但是我怀疑你是否需要
string.Copy
。为什么你想要另一个参考?我想不出您想要这样的任何常见情况(除非您使用非托管代码)。由于字符串是不可变的,因此您不能只更改字符串的内容,因此在这种情况下复制是没有用的。
鉴于您使用
string.Copy
的代码进行了更新,我想说使用 string.Copy
没有用。如果您仅在托管代码中使用 DataDictionary
,则可以进行简单的分配。
字符串新字符串 = $"{oldstring}";
String.Copy
在 .NET Core 中没有被删除——事实上它在 .NET Standard 2.0 中,因此可在所有常见的 .NET 环境中使用。
在 .NET Core 中,它是这样的:
[EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("This API should not be used to create mutable strings. See https://go.microsoft.com/fwlink/?linkid=2084035 for alternatives.")] public static unsafe string Copy(string str) { ArgumentNullException.ThrowIfNull(str); string result = FastAllocateString(str.Length); Buffer.Memmove( elementCount: (uint)result.Length, // derefing Length now allows JIT to prove 'result' not null below destination: ref result._firstChar, source: ref str._firstChar); return result; }
您可以看到
EditorBrowsableState.Never
来分散人们使用它的注意力,以及 Obsolete
和解释。解释说:
此 API 不应用于创建可变字符串。请参阅 https://go.microsoft.com/fwlink/?linkid=2084035 了解替代方案。
这意味着,如果您使用它来创建字符缓冲区以将数据复制到其中,您不应该!还有更好的选择,例如
String.Create
,它为您提供了 Span<char>
来将数据复制到其中。
但是,该消息意味着您只需担心是否实际使用它来创建可变字符串。该方法的主要用途是返回
str
的副本,使得 (object)str != String.Copy(str)
。如果您需要它用于此目的并且仅用于此目的(也许您正在ConditionalWeakTable
中使用它),那么您可以安全地使用它。
如果您仍然不确定,有一个选项可以保证创建一个新的缓冲区:
static string Copy(string str)
{
return String.Create(str.Length, str, static (buffer, s) => s.AsSpan().CopyTo(buffer));
}
请注意,如果长度为 0,则
String.Create
返回 String.Empty
,理论上,它还可以在返回结果之前对结果进行实习。当前的实现并没有走得那么远,但我实际上可以想象,这对于非常短的长度是可行的,其中可以首先在堆栈上分配缓冲区,并与内部表进行比较,以防先前创建的(弱-引用)字符串可用。