C# String.IsNullOrBlank扩展方法
我不断检查字符串字段以检查它们是否为空C# String.IsNullOrBlank扩展方法,c#,extension-methods,C#,Extension Methods,我不断检查字符串字段以检查它们是否为空 if(myString == null || myString.Trim().Length == 0) { throw new ArgumentException("Blank strings cannot be handled."); } 为了节省键入的时间,是否可以为String类创建一个具有相同效果的扩展方法?我理解如何为类实例添加扩展方法,但是如何向类添加静态扩展方法呢 if(String.IsNullOrBlank(myString))
if(myString == null || myString.Trim().Length == 0)
{
throw new ArgumentException("Blank strings cannot be handled.");
}
为了节省键入的时间,是否可以为String类创建一个具有相同效果的扩展方法?我理解如何为类实例添加扩展方法,但是如何向类添加静态扩展方法呢
if(String.IsNullOrBlank(myString))
{
throw new ArgumentException("Blank strings cannot be handled.");
}
可以将静态方法添加到现有类中吗?答案是否定的,并且该值将非常小,因为您仍然需要知道首先键入哪个类名;使用扩展方法的优点是,您可以从变量名开始,并且自动完成功能会向您显示适用于它的内容 另一个经常提出的观点是,如果扩展方法的第一个参数为null,那么它们应该总是尽快抛出异常。然而,我认为如果该方法在其名称中提到它是为检查
null
而设计的,那么该规则就太过分了
真正的问题是,在检查空引用后,您希望整洁易读地运行一些代码。捕获该模式的一种方法是使用。您可以执行以下操作:
public static bool IsNullOrBlank(this String text)
{
return text==null || text.Trim().Length==0;
}
然后这样称呼它:
if(myString.IsNullOrBlank())
{
throw new ArgumentException("Blank strings cannot be handled.");
}
这是因为C#允许您在
null
实例上调用扩展方法。您可以安全地在实例上使用扩展方法:
public static class StringExtensions
{
public static bool IsNullOrBlank(this string s)
{
return s == null || s.Trim().Length == 0;
}
}
测试用例:
string s = null;
Assert.IsTrue(s.IsNullOrBlank());
s = " ";
Assert.IsTrue(s.IsNullOrBlank());
不过这看起来有点奇怪,我想知道为什么在这种情况下需要经常检查字符串。如果你从源头上解决了它们,你以后就不必对它们如此偏执了
public static bool IsNull(this object o)
{
return string.IsNullOrEmpty(o.ToStr());
}
public static bool IsNotNull(this object o)
{
return !string.IsNullOrEmpty(o.ToStr());
}
public static string ToStr(this object o)
{
return o + "";
}
或
Bill Wagner在《更有效的C#》中建议不要让扩展函数与空实例一起工作(第183页)
原因是扩展方法应该看起来像方法调用,并且不能使用
null
实例调用方法。通过一些技巧,可以使它看起来像是添加到任何一个cs文件中的字符串类:
namespace JDanielSmith
{
public static class String
{
public static bool IsNullOrBlank(string text)
{
return text == null || text.Trim().Length == 0;
}
}
}
(注意,这不是一种扩展方法,请参见我的评论)
然后,在其他一些CS文件中:
using String = JDanielSmith.String;
namespace Foo.Bar.Baz
{
class Program
{
static void test(string myString)
{
if (String.IsNullOrBlank(myString))
{
throw new ArgumentException("Blank strings cannot be handled.");
}
}
...
请注意String.IsNullOrBlank()的“所需”语法。我不一定建议您以这种方式进行操作,只是指出如何进行设置以使代码正常工作。现有答案的过载可能是:
public static bool IsNullOrBlank(this String text, Action<String> doWhat)
{
if (text!=null && text.Trim().Length>0)
doWhat(text);
}
我知道这是一个老问题,但由于它被打断了,而且还没有被提及,从.NET 4.0开始,您可以简单地使用来实现相同的结果。有点晚了。但是您也可以将代码放在扩展方法中引发异常。我有两种方法(用于
ArgumentNullException
和NullReferenceException
)
虽然这个问题是十多年前提出的,但我发现没有人提到有一个内置的字符串方法来处理这个问题
因此,请改用
string.IsNullOrWhitespace()
。无需对任何内容进行黑客攻击,使用语言功能就可以了。不同的是,IsNullOrEmpty不检查只包含空格字符的字符串。此外,如果调用Trim()且字符串为null,则会出现NullReferenceException。很抱歉,答案中没有太多的价值,也有误导性,因此-1.问题是,在检查是否为空(返回到1)之前,您无法修剪:(.我想我可以创建一个新的静态类并调用该方法,如果将它放在字符串intellisense上就好了。我已经完全删除了第一部分,我同意这是有误导性的。如果要测试的字符串为null,则将不起作用,因为Trim()方法需要一个对象。IsNullOrEmptyTrimmed(null);我认为get错误是因为value.Length for value为null,throw null referenceexception,不是吗?第一个示例不会返回true或无限递归吗?@pinkfloydx33:Hm..可能会。我忘记了。谢谢,edited。我不太喜欢这个。IsNull和IsNotNull的语义令人惊讶。为什么要添加s在ToStr中将字符串.Empty转换为o?它对对象更有用(例如,当需要对Eval(“blalblabla”)执行某些操作时),但也可以用于字符串。为什么不喜欢这样呢?从概念上讲,(o==null)!=(o.ToStr==string.Empty)。如果我想测试一个引用是否为null,最好只测试它是否为null。(我不是你的反对票,只是说我想我理解为什么会发生这种情况。)有趣的是,C#不允许你调用带有空实例的方法,因为它会发出callvirt IL指令。但是,在IL中,如果你通过“call”进行调用指令您可以对空实例调用。@dan-我不认为名称中包含空检查的方法不适合扩展方法。@Maslow-agreed.C#允许对空对象使用扩展方法,所以请使用它。如果出现这种情况,您可以从扩展方法抛出NullReferenceException来模拟实例方法的行为参数为null,但提供了比“对象引用未设置为对象实例”更具描述性的错误消息任何使用您的方法的示例?@alhambraeidos-done,或者您正在寻找一个显示更具体/有用场景的示例?这会导致大量名称混淆。现在,编码人员必须再次检查该字符串是JDanielSmith.String还是System.String…啊!上面描述的扩展方法显然更容易理解@code4life是对的:呃!String.IsNullOrWhiteSpace是一个静态方法,扩展更容易使用。甚至String.IsNullOrEmpty也更容易用作扩展方法-请参阅
using String = JDanielSmith.String;
namespace Foo.Bar.Baz
{
class Program
{
static void test(string myString)
{
if (String.IsNullOrBlank(myString))
{
throw new ArgumentException("Blank strings cannot be handled.");
}
}
...
public static bool IsNullOrBlank(this String text, Action<String> doWhat)
{
if (text!=null && text.Trim().Length>0)
doWhat(text);
}
Name.IsNullOrBlank(name=>Console.WriteLine(name));
// strings
public static bool NullBlankCheck(this string s, string message = "",
bool throwEx = true)
{
return Check<NullReferenceException>(s.IsNullOrBlank(), throwEx, message);
}
public static bool NullBlankCheckArgument(this string s, string message = "",
bool throwEx = true)
{
return Check<ArgumentException>(s.IsNullOrBlank(), throwEx, message);
}
private static bool Check<T>(bool isNull, bool throwEx, string exceptionMessage)
where T : Exception
{
if (throwEx && isNull)
throw Activator.CreateInstance(typeof(T), exceptionMessage) as Exception;
return isNull;
}
public static bool IsNullOrBlank(this string s)
{
return string.IsNullOrEmpty(s) || s.Trim().Length == 0;
}
Assert.Throws<NullReferenceException>(() =>
{
"".NullEmptyCheck();
});
Assert.Throws<ArgumentException>(() =>
{
"".NullEmptyCheckArgument();
});
public void Method(string someStr)
{
someStr.NullBlankCheckArgument();
// do something
var str = someMethod();
str.NullBlankCheck();
}