我想截断一个字符串,使其长度不超过给定值。我正在向数据库表写入数据,并希望确保写入的值满足列数据类型的约束。
例如,如果我能写以下内容,那就太好了:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
不幸的是,这会引发异常,因为maxLength通常超过字符串值的边界。当然,我可以写一个像下面这样的函数,但我希望这样的东西已经存在了。
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
执行此任务的难以捉摸的API在哪里?有吗?
所有其他答案都没有考虑到Span的性能,它比。net中字符串类型的Substring的性能更好
如果你还不知道有一个版本的系统。内存(为以下情况提供了Span, ReadOnlySpan, Memory和ReadOnlyMemory:
这样的简单实现可以如下所示:
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.AsSpan(0, maxLength).ToString(); /* Note the use of AsSpan instead of Substring. */
}
return value;
}
该方法理论上可以返回Span<char>,以避免使用Span<T>的ToString()成员分配新字符串。
The BCL itself internally uses Span's, ReadOnlySpan's, Memory's, and ReadOnlyMemory's where possible to avoid issues and to help optimize the code, especially when you compile arrays that are known at compile time and so using an property that returns that new'd up array as an ReadOnlySpan<byte> actually optimizes the code at runtime as then the JIT would not call memcpy on the data and instead uses it since it just returns a Span and as such is a window to the data that is already allocated ahead of time resulting in:
更少的分配。
更少的分配时间。
使代码总体上更快地使用。
我更喜欢jpierson的答案,但我在这里看到的示例都没有处理无效的maxLength参数,例如当maxLength < 0时。
可以选择在try/catch中处理错误,将maxLength参数min限制为0,或者如果maxLength小于0则返回空字符串。
未优化的代码:
public string Truncate(this string value, int maximumLength)
{
if (string.IsNullOrEmpty(value) == true) { return value; }
if (maximumLen < 0) { return String.Empty; }
if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
return value;
}