我怎样才能 Non-kludgily/tediously 阻止向 class 成员写入空字符串的尝试?

How can I Non-kludgily/tediously prevent the attempt to write empty strings to class members?

我有一个 class 代表这样一个 Sharepoint 列表:

private class ListColumns
{
    public String li_requestDate { get; set; }
    public String li_paymentAmount { get; set; }
    public String li_payeeName { get; set; }
    public String li_remitAddressOrMailStop { get; set; }
    . . .

我阅读以前保存到 Sharepoint 列表的项目是这样的:

private List<ListColumns> ReadFromList()
{
    List<ListColumns> lcList = new List<ListColumns>();

    using (SPSite site = new SPSite(siteUrl))
    {
        using (SPWeb web = site.RootWeb)
        {
            SPList list = web.Lists[listTitle];
            SPListItemCollection SpListColl = list.Items;
            foreach (SPListItem item in SpListColl)
            {
                ListColumns lc = new ListColumns();
                lc.li_requestDate = item["RequestDate"].ToString();
                lc.li_payeeName = item["PayeeName"].ToString();
                lc.li_remitAddressOrMailStop = item["RemitAddressOrMailStop"].ToString();
                . . .

如果分配给 class 成员的值是空字符串,则此代码会崩溃 - IOW,尝试将空字符串分配给这些 class 成员中的任何一个会导致 ReadFromList()' s catch 方法的行为就好像已经到达了指向它的 GOTO 语句(并且没有收集 200 美元——或任何金额,就此而言)。

我可以使用 kludgy/tedious 代码来防止这种情况发生:

if (!(String.IsNullOrEmpty(item["RequestDate"].ToString())))
{
    lc.li_requestDate = item["RequestDate"].ToString();
}
if (!(String.IsNullOrEmpty(item["PayeeName"].ToString())))
{
    lc.li_payeeName = item["PayeeName"].ToString();
}
. . .

(等等等等。与朋友的广告词等令人作呕)

...但有一个暗示必须有一个 "more better" 方式。谁能具体证实我的直觉?

更新

正在尝试 Alex 的代码:

item.SetAsString("RequestDate", x => lc.li_requestDate = x);

我仍然得到,"Object reference not set to an instance of an object" 如果值为空。

MatteoSP 的代码:

Apply(item, "RequestDate", x => lc.li_requestDate = x);

...甚至无法编译;我收到两条错误消息:

'DirectPaymentSectionsWebPart.DPSVisualWebPart.DPSVisualWebPartUserControl.Apply(System.Collections.Generic.IDictionary, string, System.Action)' 的最佳重载方法匹配有一些无效参数

-和:

参数 1:无法从 'Microsoft.SharePoint.SPListItem' 转换为 'System.Collections.Generic.IDictionary'

更新 2

我的 kludgy/verbose 代码,我认为它至少可以工作:

if (!(String.IsNullOrEmpty(item["RemitAddressOrMailStop"].ToString())))
{
    lc.li_remitAddressOrMailStop = item["RemitAddressOrMailStop"].ToString();
}

...也因迟钝的“对象引用未设置到对象实例”而失败。

是否有必要通过在写入 List 时向每个否则为空的值写入一个“”(space) 来进一步提升 Kludginess?

更新 3

我也尝试了 Shaw 发布的想法 here,但结果还是一样(崩溃,“对象引用未设置为对象的实例 ")

你可以这样定义:

    static void Apply(IDictionary<string, object> dict, string key, Action<string> setter)
    {
        if (!dict.ContainsKey(key) || string.IsNullOrEmpty(dict[key].ToString()))
            return;

        setter(dict[key].ToString());
    }

然后这样使用:

Apply(item, "RequestDate", x => lc.li_requestDate = x);
Apply(item, "PayeeName", x => lc. li_payeeName = x);

使用扩展方法如何

public static class ListItemExtensions
{
    public static void SetAsString(this SPListItem item, string colName, Action<string> destSetter)
    {
        if (item != null)
        {
            var col = item[colName];
            if (col != null)
            {
                var colVal = col.ToString();
                if (!string.IsNullOrEmpty(colVal))
                    destSetter(colVal);
            }
        }
    }
}

用法:

 item.SetAsString("RequestDate", x => lc.li_requestDate = x);

在谨慎处理数据后,我让它开始工作。

从列表中读取的代码还是这样:

if (!(String.IsNullOrEmpty(item["RequestDate"].ToString())))
{
    lc.li_requestDate = item["RequestDate"].ToString();
}

...但是写入列表的代码已经增长 真的 腰带和吊带,像这样:

if (null != boxFundingApproverPrinted)
{
    if (String.IsNullOrEmpty(boxFundingApproverPrinted.Text))
    {
        spli["FundingApproverName"] = "[left blank]";
    }
    else
    {
        spli["FundingApproverName"] = boxFundingApproverPrinted.Text;
    }
}
else
{
    spli["FundingApproverName"] = "[left blank]";
}

...诚然,它很笨拙(笨拙且乏味),但它确实有效...(我在完成所有操作后看到了 Alex 的更新)。