2017-01-20 36 views
0

我正在使用工廠來隱藏我想傳遞一個已知長度數組的構造函數。我想使工廠方法足夠普遍,它將處理來自包含任意數量參數(太少,太多,或者只是正確數字)的客戶端的輸入。C#從params參數複製到特定長度的數組

有沒有一種方法,使用更多的慣用C#來限制傳遞給工廠方法的參數參數,所以我可以肯定它有我的創建對象的正確長度?

using System.Linq; 

public class GridFactory 
{ 
    public IGrid Create2DGrid(params bool[] inputWrappingRules) 
    { 
     // Yikes! This works, but it's kind of a monster: 
     var gridWrappingRules = new bool[2]; 
     inputWrappingRules.Take(2).ToArray().CopyTo(gridWrappingRules, 0); 

     // These are susceptible to errors: 
     // var gridWrappingRules = new bool[2]; 
     // System.Array.Copy(inputWrappingRules, gridWrappingRules, 2); 
     // --or-- 
     // var gridWrappingRules = new System.ArraySegment<bool>(inputWrappingRules, 0, 2).Array; 

     return new TwoDGrid(gridWrappingRules); 
    } 
} 

public class TwoDGrid : IGrid 
{ 
    private bool[] _wraps; 

    internal TwoDGrid(bool[] wraps) 
    { 
     _wraps = wraps; 
    } 

    // I want to use _wraps[0] and _wraps[1] in my methods here... 
} 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var gridFactory = new GridFactory(); 
     var grid1 = gridFactory.Create2DGrid(); 
     var grid2 = gridFactory.Create2DGrid(true); 
     var grid3 = gridFactory.Create2DGrid(false, true); 
     var grid4 = gridFactory.Create2DGrid(false, true, true); 
     /* 
     *So, then, 
     * grid[1]._wraps is { false, false }, 
     * grid[2]._wraps is { true, false }, 
     * grid[3]._wraps is { false, true }, and 
     * grid[4]._wraps is { false, true }. 
     */ 
    } 
} 
+0

不在編譯時,除非'CodeContracts'可以驗證長度。在運行時您可以在構造函數(或工廠)中進行檢查,如果不期望數組中的項數,則會拋出一個'ArgumentOutOfRangeException'。 – Igor

+0

我不明白爲什麼你應該允許客戶通過更少或更多的參數,而不是你已經知道「正確」的尺寸。 – HimBromBeere

回答

0

由於您正在爲數組使用值類型,因此您可以創建另一個需要的固定大小的數組,並僅複製元素。

// outputCount is an int with the number of elements you want to pass down. 
var outputArray = new bool[outputCount]; 
Array.Copy(inputArray, outputArray, Math.Min(inputArray.Length, outputCount)); 

// pass down outputArray here. 
+0

我沒有想過將一個計算的'length'參數傳遞給'Array.Copy()',這正是我想要的,簡潔。謝謝。 – gooberwonder

0

不是真的,因爲params是專門設計用於允許調用方傳遞任意數量的參數。

如果您需要固定數量的參數,請避免使用params

// Fixed at 2 parameters 
public IGrid Create2DGrid(bool rule1, bool rule2) 
{ 
    if (twoParamsOk) 
    { 
     Create2DGrid(new [] { rule1, rule2 }); 
    } 
} 

// Fixed at 3 parameters 
public IGrid Create2DGrid(bool rule1, bool rule2, bool rule3) 
{ 
    if (threeParamsOk) 
    { 
     Create2DGrid(new [] { rule1, rule2, rule3 }); 
    } 
} 

private IGrid Create2Grid(bool[] rules) 
{ 
    if (rules.Length != 2) 
     throw new ArgumentException("need 2 rules); 
}