在C#中构建字符串数组并检查空值?

3

我正在创建一个字符串数组,其中包含来自自定义对象的值,就像这样:

foreach(MyObject o in MyObjectList)
    string[] myArray = new string[] {o.id, o.number.toString(), o.whatever, ...}

这里的问题是,任何一个值都可能是NULL,这当然会导致代码崩溃。假设o.number是NULL而其他值不是……在这种情况下,我仍然想填充其他值,并将"NULL"作为字符串放入o.number的位置。

除了检查每个值,有没有更好的方法呢?

谢谢 :)


使用可空类型怎么样? - hungryMind
MyObject已经被定义,我无法更改它...如果我在可空类型上调用toString会发生什么? - grady
可空类型对于非空值的工作方式与它们的非可空基础类型相同。不幸的是,对于 null 值,它取决于:如果装箱,则会抛出 NullReferenceException 异常,因为它为空;如果强类型化,则返回空字符串。 - Eamon Nerbonne
7个回答

3

您需要检查每个值,但使用 ?? 操作符不应该太麻烦,所以只需针对每个值执行以下操作:

o.id ?? "NULL"

o.id ?? "NULL" 是可以的,但如果 o.number 为空,则不可以使用 o.number.toString(),因为你在空指针引用上调用了 toString() 函数,它不会返回 null 而是会抛出异常。 - Matten

3

对于与此相关的项目,我经常定义一个扩展方法ToStringOrNull,如下所示:

public static string ToStringOrNull(this object o) { 
    return o == null ? null : o.ToString();
}

为避免intellisense污染,如果您恰好有一组有用的类型集合适用于ToStringOrNull,则可以(我有时会这样做)避免将扩展添加到object,而是复制并粘贴一堆相关类型的副本。该函数很容易写成一行代码,因此为了解决这种重复,使用代码生成工具是过度的。
然后,如果您希望将字符串null替换为某些占位符文本,请使用空值合并运算符。
例如:
string[] myArray = new [] {
    o.id, o.number.ToStringOrNull(), o.whatever, ...
};// .Select(s=>s??"NULL").ToArray(); //uncomment to replace null with "NULL"

2
这是我的建议。
实现一个名为 "AsString" 的扩展方法,可以按照以下方式编写代码:
namespace ConsoleApplication1
{
    public static class ObjectExtensions
    {
        public static string AsString(this object source)
        {
            if (source != null)
            {
                return source.ToString();
            }
            else
            {
                return null;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            object a = null;
            object b = "not null";

            string someText = a.AsString();
        }
    }
}

现在,如果整个引用具有对象,则可以返回字符串;如果引用没有对象,则返回null。

这是一个不错的想法 - 但是,这与我写的基本上是等价的(但更长)。 - Eamon Nerbonne
完全是的,我几乎与您同时写出了答案... 哎呀! - Matías Fidemraizer

1
你只需要检查那些可以为空的字段,例如
foreach(MyObject o in MyObjectList)
  string[] myArray = new string[] {
    o.id,
    (o.number == null ? "NULL" : o.number.toString(),
    o.whatever, ... };

1

你需要检查每个值。一个简单的方法是这样的:

string nullStr = "NULL";
foreach (MyObject o in MyObjectList) {
    string[] myArray = new string[] {
        o.id,
        (o.number ?? nullStr).ToString(),
        (o.whatever ?? nullStr).ToString(),
        ...
    };
}

0
我会选择以下两个选项之一:
1.像其他人建议的那样,为您想要检查 null 的类型实现扩展方法。
2.如果您不能/不想使用扩展方法,则可以在 MyObject 中定义一个帮助方法,该方法将接受一个对象并基本上执行相同的 null 检查。
string Check(object o)
{
    return o == null ? null : o.ToString(); 
}

然后,您将使用此方法调用包装要使用的每个属性。

foreach(MyObject o in MyObjectList)
    string[] myArray = new string[] {o.id, o.Check(o.number), o.whatever, ...}

你甚至可以将它变成一个本地变量:Func<object,string> stringize = o=>o==null?null:o.ToString(); - Eamon Nerbonne

0
如果你想将非空元素放入数组中,那么你需要检查每个值。这是无法避免的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接