作为我对此代码所做的重构的一部分,我遇到了这段代码,我正在讨论什么更正确/更有效?
之前:
string CutHeadAndTail(string pattern)
{
if (pattern[0] == '*')
{
pattern = pattern.Substring(1);
}
if (pattern[pattern.Length - 1] == '*')
{
pattern = pattern.Substring(0, pattern.Length - 1);
}
return pattern;
}
后:
private string RemoveAllowedAstrisks(string pattern)
{
pattern = pattern[0] == '*'?pattern.Substring(1): pattern;
pattern = pattern[pattern.Length - 1] == '*' ? pattern.Substring(0, pattern.Length - 1) : pattern;
return pattern;
}
什么更好?
我在想pattern = pattern[0] == '*'?pattern.Substring(1): pattern;
这一行
意思是,从可读性的角度来看,我更喜欢第二种。但另一方面,这个表达式的含义是以下两个选项:
pattern[0]=='*'
- >在这种情况下,模式将更改为pattern.Substring(1)
else
- > pattern = pattern
如果我选择第一种方式(忽略命名等),我只有第一种选择:
if (pattern[0] == '*')
{
pattern = pattern.Substring(1);
}
return pattern;
底线:行pattern = pattern
会花费更多内存吗?
答案 0 :(得分:1)
如果您允许从字符串的开头和结尾剪切所有*
个字符(如"**some string**"
),那么您可以这样做:
private string RemoveAllowedAstrisks(string pattern)
{
return pattern?.Trim('*');
}
答案 1 :(得分:0)
执行此操作的最佳方法可能是via a regex
using System.Text.RegularExpressions;
...
private static Regex leadingTrailingAsterisks = new Regex("(^\\*)|(\\*$)");
private static string RemoveAllowedAsterisks(string pattern)
{
return leadingTrailingAsterisks.Replace(pattern, "");
}
答案 2 :(得分:0)
我更喜欢第一种方式,因为它更简单,并且使编译器更容易进行任何优化。
说实话,我不知道编译器是否会在第二种方法中优化pattern = pattern
。它可能。只有速度测试才能帮助您确定。
就个人而言,我发现第二种方法更简洁但不易读。如果我不需要这样做,我也不会编写为自己分配变量的代码。
更可读的方式是使用string.Trim()
,但我认为效率较低。
答案 3 :(得分:0)
我已检查生成的IL代码以查看创建的内容。
IL_000e: ldloc.0 // hello
IL_000f: ldc.i4.0
IL_0010: callvirt instance char [mscorlib]System.String::get_Chars(int32)
IL_0015: ldc.i4.s 42 // 0x2a
IL_0017: beq.s IL_001c
IL_0019: ldloc.0 // hello
IL_001a: br.s IL_0023
IL_001c: ldloc.0 // hello
IL_001d: ldc.i4.1
IL_001e: callvirt instance string [mscorlib]System.String::Substring(int32)
IL_0023: stloc.0 // hello
如您所见,如果运行逻辑语句的ldloc.0
分支(:
),则IL_0019
被激活。在此之后,代码跳转到执行IL_0023
的{{1}}。
这可能是值类型的问题,但stloc.0
是引用类型,并且此类赋值根本不会影响内存。为了证明这一点,我创建了一个大字符串并运行了一些string
分配。堆大小永远不会改变。
value = value
答案 4 :(得分:0)
如何进行以下操作:计算是从前面还是后面或两者中修剪一个字符,如果是,则返回一个子字符串,否则返回字符串本身。
string CutHeadAndTail(string pattern)
{
var s = pattern[0] == '*' ? 1 : 0;
var e = pattern[pattern.Length - 1] == '*' ? 1 : 0;
return (s > 0 || e > 0) ?
pattern.Substring(s, pattern.Length - s - e) :
pattern;
}