2010-07-27 53 views
1

我有一個代碼:我該如何簡化這部分代碼?

byte[][][] file = GetConfigData(); 

    if (file == null) 
     return; 

    int pages = 0; 
    for (i = 0; i < file.Length; i++) 
    { 
     if (file[i] != null) 
     { 
      for (j = 0; j < file[i].Length; j++) 
      { 
       if (file[i][j] != null) 
       { 
        pages++; 
       } 
      } 
     } 
    } 

我怎麼能簡化呢?

請提供2個版本:

  1. 用於.NET 2.0
  2. 用於.NET 3.5(LINQ)
+1

什麼版本的框架?我相信有人會想出一個LINQ-One-Liner。;) – Bobby 2010-07-27 08:15:53

+0

鮑比,感謝您的糾正。我在一個問題中添加了它。 – alexander 2010-07-27 08:18:10

+0

只要編譯器爲3.0+,你就可以使用LINQ for .NET 2.0,那麼你需要什麼?可以在2.0上運行的例子或者可以使用2.0C#編譯器編譯的例子? – 2010-07-27 10:05:35

回答

3

如果你的意思是 '我怎​​樣才能使它更容易理解',那麼我的第一個建議是使用更有意義的變量名稱。

它會更長,但更簡單。

你也可以使用'foreach'而不是'for' - 這會失去一些索引變量。

最後,你可以使用一些毛茸茸的linq線,以一種功能性的風格來完成這一切,但在任何初學者的意義上這都不會更簡單。

+0

Will Dean,我的意思是:我不喜歡在那個代碼中檢查空值,所以_maybe_有沒有更好的方法來讓頁面變量沒有空檢查? – alexander 2010-07-27 08:26:28

+0

如果您可以保證'GetConfigData()'不會在數組的任何級別返回空值,那麼您可以放棄空檢查 - 否則它們應該保留。你控制'GetConfigData()'嗎? – Rup 2010-07-27 08:42:24

+0

Rup,不,我不控制GetConfigData()。我通過C++模塊從設備獲取該字節數組(我使用pinvoke)。所以我不能保證它沒有數據,一些數據,完整的數據,不完整的數據...... – alexander 2010-07-27 09:27:33

5

我不習慣.NET 2.0,但我可以爲您提供一些.NET 3.5 Linq查詢。

這就是:

pages = (from i in file 
     where i != null 
     from j in i 
     where j != null 
     select j).Count(); 

但正如你所看到的和威爾Dean說,哪怕是簡單的它不會自動使之更容易理解。 我想補充一點,當你在代碼簡化方面做得太過分時,你也可能在代碼不可讀性方面走的更遠。

我更喜歡有意義且易於閱讀的代碼,因爲隨着時間的推移,硬件得到了改進,所以編寫得很好且易於閱讀的代碼將會更快,並且易於維護,但是更短且難以理解的代碼將會保持不可讀。

+0

感謝您的回答,無論如何。而且,我同意,Dean會是對的。 – alexander 2010-07-27 09:30:09

+0

+1可讀代碼。 – Marko 2010-07-27 10:35:29

+1

您的代碼將運行在.NET 2.0運行時(它將需要C#3.0編譯器的原因) – 2010-07-27 15:56:37

0

你可以改變GetConfigData返回字節數組以外的東西嗎?我猜字典會更容易使用。

代碼更容易,如果你使用continue關鍵字,以減少它築巢的量來管理,因爲使用continue明確地說,在這種情況下,我們應該跳到下一個迭代讀者

除非您知道底層數據將始終有值,否則無法刪除空檢查。

byte[][][] file = GetConfigData(); 

if (file == null) 
    return; 

int pages = 0; 
foreach (var xxx in file) 
{ 
    if (xxx == null) 
     continue; 
    foreach (var yyy in xxx) 
    { 
     if (yyy == null) 
      continue; 

     pages++; 
    } 
} 

我只是用xxxyyy作爲變量的佔位符的名字,因爲我不知道他們代表什麼。

+0

不幸的是,我無法更改GetConfigData()。 – alexander 2010-07-27 09:31:00

2

這是我在重寫代碼時的注意事項。因爲我基本上不知道數組代表的是什麼,但我更改了名稱,使其在您的域中有意義,我認爲這比讀取原始數據更容易閱讀:)

byte[][][] file = GetConfigData(); 

if (file == null) 
    return; 

var existingFiles = files.Where(file => files != null); 
var pages = existingFiles.Count(subFile => subFile != null); 
1
static void Main(string[] args) 
{ 
    byte[][][] files = new byte[][][] 
    { 
     new byte[][] { new byte[] { 0x1, 0x2 }, null, new byte[] { 0x3, 0x4 } }, 
     new byte[][] { null, new byte[] { 0x5, 0x6 }, new byte[] { 0x7, 0x8 } }, 
     new byte[][] { null, null, new byte[] { 0x9, 0x10 } }, 
     new byte[][] { null, null, null }, 
    }; 

    var pages = Test(files); // 5 
} 

static int Test(byte[][][] files) 
{ 
    return files.SelectMany(f => f).Count(b => b != null); 
}