C# 处理数据,如果为空则继续

C# 处理数据,如果为空则继续,c#,object,process,null,C#,Object,Process,Null,例如,我必须处理一些数据项 User u = NotMyObject.GetUser(100); ProcessProperty(u.FirstName); ProcessProperty(u.Surname); ProcessProperty(u.Phone.Work); ProcessProperty(u.Phone.Mobile); ... ProcessProperty(u.Address.PostCode); 假设所有属性都以字符串形式从GetUser(…)返回。我希望Process

例如,我必须处理一些数据项

User u = NotMyObject.GetUser(100);
ProcessProperty(u.FirstName);
ProcessProperty(u.Surname);
ProcessProperty(u.Phone.Work);
ProcessProperty(u.Phone.Mobile);
...
ProcessProperty(u.Address.PostCode);
假设所有属性都以字符串形式从GetUser(…)返回。我希望ProcessProperty所做的与此无关(例如,可能将值写入文件),但它看起来像:

private void ProcessProperty(string data) {
...
}
我的问题是,u.Phone和u.Address可能为NULL。如何处理“User u”对象而不将每个ProcessProperty(…)调用放入try/catch块

抱歉,如果问题的格式不好,我仍然掌握发帖的窍门

非常感谢。N.

你可以试试(也许它不优雅):


如果您可以编辑用户类,我将更改属性上的设置代码,该属性可以为null,以将null转换为String。Empty

如果您可以控制ProcessProperty函数,则只需将其添加到函数中即可

if(data == null) return;
否则你可以写这个

if(u.Phone != null)
     ProcessProperty(u.Phone.Work);

使用lambda表达式和扩展方法生成单子:

public static class ObjectExt
{
    public static TProp GetPropOrNull<TObj, TProp>(this TObj obj, 
        Func<User,TProp> getProp)
        where TObj : class
        where TProp : class
    {
        if (obj == null)
            return null;
        else
            return getProp(obj);
    }
}
该方法不使用长点链(如u.Phone.Work.Whatever),如果第一个属性中的任何一个为null,该点链就会失败,而该方法会短路,并在看到null时立即返回null。如果您必须使用其他可能不是非常细心的程序员的类中的某个属性,那么这可以将代码大大缩短(而不是使用if检查)。我认为在下面的文章中,作者将方法名
一起使用,而不是
getPropNull
,这样甚至可以进一步缩短它

参考资料:


如果不能更改<强> PurralPrime<强>考虑包装:

private void ProcessPropertySafe(string data) 
{
    if (data != null)
    {
        ProcessProperty(data);
    }
}
或者像int.Parse()和int.TryParse()那样:

私有布尔属性(字符串数据)
{
尝试
{
过程属性(数据);
返回true;
}

catch//
ProcessProperty
在数据为null时是否引发异常?@sll:如果u.Phone为null,当您尝试访问其工作属性时,它应该引发异常…我不明白。您认为所有属性都是从GetUser返回的(…)作为字符串。然后您访问
u.Phone.Work
。您之前的语句指出
Phone
应该是字符串。或者实际上是因为
User
公开的属性可以是任何类型,但我们只将字符串传递给
ProcessProperty
?实际上,
string
不公开
Work
code>Mobile
,也不是
PostCode
属性。如果u.Phone为null,并且我尝试访问u.Phone.Work,它确实会引发异常…\u认为所有最终属性都是从GetUser返回的(…)作为string_,这看起来是一个直截了当的方法,当我有更多的时间时,我会看看moand的东西。ProcessPropertyRapper更好的名字是ProcessPropertySafe
public static class ObjectExt
{
    public static TProp GetPropOrNull<TObj, TProp>(this TObj obj, 
        Func<User,TProp> getProp)
        where TObj : class
        where TProp : class
    {
        if (obj == null)
            return null;
        else
            return getProp(obj);
    }
}
u.GetPropOrNull(obj => obj.Phone).GetPropOrNull(obj => obj.Work);
u.GetPropOrNull(obj => obj.Phone).GetPropOrNull(obj => obj.Home);
private void ProcessPropertySafe(string data) 
{
    if (data != null)
    {
        ProcessProperty(data);
    }
}
private bool TryProcessProperty(string data) 
{
    try
    {
        ProcessProperty(data);
        return true;
    }
    catch // <- That's not clean ...
    {
        return false;
    }
}