简体   繁体   English

如何避免以优雅的方式创建不需要的对象?

[英]How to avoid creating unneeded object in an elegant way?

The root of my question is that the C# compiler is too smart. 我的问题的根源是C#编译器太聪明了。 It detects a path via which an object could be undefined, so demands that I fill it. 它检测到一个可以通过其定义对象的路径,因此要求我填充它。 In the code, I look at the tables in a DataSet to see if there is one that I want. 在代码中,我查看DataSet中的表以查看是否存在我想要的表。 If not, I create a new one. 如果没有,我会创建一个新的。 I know that dtOut will always be assigned a value, but the the compiler is not happy unless it's assigned a value when declared. 我知道dtOut将始终被赋值,但编译器不满意,除非在声明时赋值。 This is inelegant. 这是不优雅的。

How do I rewrite this in a more elegant way? 如何以更优雅的方式重写它?

             System.Data.DataTable dtOut = new System.Data.DataTable();
            .
            .
            // find table with tablename = grp
            // if none, create new table
            bool bTableFound = false;
            foreach (System.Data.DataTable d1 in dsOut.Tables)
            {
                string d1_name = d1.TableName;
                if (d1_name.Equals(grp))
                {
                    dtOut = d1;
                    bTableFound = true;
                    break;
                }
            }

            if (!bTableFound) dtOut = RptTable(grp);

You can rewrite your method like so: 您可以像这样重写您的方法:

System.Data.DataTable dtOut = dsOut
                                   .Tables
                                   .Cast<System.Data.DataTable>()
                                   .FirstOrDefault(t => t.TableName.Equals(grp)) 
                                 ?? RptTable(grp);

That initial value can be null . 该初始值可以为null The compiler doesn't require you to create an instance ; 编译器不要求您创建实例 ; it just requires you to assign a value. 它只需要你分配一个值。

System.Data.DataTable dtOut = null;  // compiler is now happy
// rest of code as before
            ...program...
            {
               System.Data.DataTable dtOut = GetDataTableByName(grp, dsOut);
            }

            public DataTable GetDataTableByName(string grp, object dsOut)
            {
              foreach (System.Data.DataTable d1 in dsOut.Tables)
                {                    
                   if (d1.TableName.Equals(grp))
                     return RptTable(grp)
                }
              return null;
            }

If I've interperated your naming correctly. 如果我正确地填写了你的命名。

var dtOut = dsOut != null && dsOut.Tables != null && dsOut.Tables[grp] != null 
            ? dsOut.Tables[grp]
            : RptTable(grp);

HTH HTH

I like Otávio's answer, but here's an alternate approach anyway. 我喜欢Otávio的回答,但无论如何,这是另一种方法。 You can shove the foreach loop down into its own method, something like: 您可以将foreach循环推送到自己的方法中,例如:

static System.Data.DataTable
getDataTable ( System.Data.DataTable[] tables, String grp )
{
    foreach (System.Data.DataTable d1 in tables)
        {
            string d1_name = d1.TableName;
            if (d1_name.Equals(grp))
            {
                return d1;
            }
        }
    return null;
}

This lets you simplify your original method to: 这使您可以简化原始方法:

System.Data.DataTable dtOut = getDataTable(dsOut.Tables, grp);
if (!dtOut) dtOut = RptTable(grp);

If you want elegance, go LINQ: 如果你想要优雅,那就去LINQ吧:

var dtOut = 
  dsOut.Tables.FirstOrDefault(t => t.TableName == grp)
  ?? RptTable(grp);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM