2017-02-14 82 views
0

編輯:最初,這個職位的例子已經處理哈希碼,所以你會看到一些使用param.GetHashCode(),而不是(1 +參數)的意見。爲了獲得更多的信息,我已經改變了函數來計算一個加上某個數字的絕對值。C# - 限制範圍到三元語句

假設我想創建一個函數來計算某個整數的絕對值(不使用Math.Abs​​)。我可以寫類似於:

int absoluteValueOfOnePlus(int param) 
{ 
    int onePlusParam= 1 + param; 
    return ((onePlusParam> 0) ? (onePlusParam) : (-onePlusParam)); 
} 

我期待onePlusParm的範圍限制在三元語句中 - 類似於:

int absoluteValueOfOnePlus(intparam) 
{ 
    return (((int onePlusParam = 1 + param) > 0) ? (onePlusParam) : (-onePlusParam)); 
} 

我明白,這不是有效的C# ,但它證明了我正在嘗試執行的一個很好的例子 - 創建一些僅存在於三元運算符範圍內的變量。

+3

「我期待壓縮這個方法到一條線」。你能解釋爲什麼你需要這樣做嗎? – openshac

+1

你可以做'int i;返回i = param.GetHashCode()> 0?我: - 我;'...我不會,但你可以。 –

+0

@openshac,它比限制範圍更多。如果函數大得多,我會在函數的其餘部分存在。在三元語句中使用聲明會將範圍限制在三元範圍內 - 語句完成後,我將被刪除。 –

回答

3

三元表達式的部分是表達式。如果語言設計師允許你要求的東西,他們可能會爲所有的表達方式而不是三元表達方式。那麼你也可以做if ((int n = foo()) != 0) bar(n);

在C#中,聲明是語句,而不是表達式。所以答案是否定的,你不能這樣做。然而,for語句可以採取宣言,這樣你就可以得到一個說法最接近的是這樣的:

for (int i = param.GetHashCode();;) 
    return (i > 0) ? i : -i; 

這在技術上是一個單獨的語句,儘管是化合物中的一個,並在兩行。但是這看起來很糟糕的代碼,我不會那樣寫。

如果您主要關注的是最小化的i範圍,然後用小範圍吧:

int positiveHash(string param) 
{ 
    // Some statements here... 
    // ... 

    // Start a small scope 
    { 
     int i = param.GetHashCode(); 
     if (...) 
      return ((i > 0) ? (i) : (-i)); 
    } 

    // Some more C# statements here. 
    // i is out of scope here. 
} 
+0

謝謝你的解釋。我的問題的目標是限制我的範圍 - 不一定是乾淨的代碼,所以這是完美的。 –

1

我就簡單的寫:

int GetPositiveHash(string param) 
{ 
    return Math.Abs(param.GetHashCode()); 
} 

int GetPositiveHash(string param) 
{ 
    int hashCode = param.GetHashCode(); 

    return Math.Abs(hashCode); 
} 

艾滋病的可讀性,可維護性,更重要的是在這種情況下,避免premature optimization which is the root of all evil

如果您真的擔心性能問題,請查看您的代碼並查看您最大的瓶頸所在。如果GetPosiitiveHash()造成最大的瓶頸,我會很驚訝。

您可能想看看.Net Framework source codeString.GetHashCode()。你會發現一個三元運算符將會比GetHashCode()方法中的內存節省很少。

值得記住:

報價的完整版本是「我們應該忘記小 效率,講的時候約97%:過早的優化是一切罪惡的 根」我同意這一點。它通常不值得 花費大量的時間微優化代碼之前,其明顯的性能瓶頸 。

The fallacy of premature optimization

+0

我給出的概念比其他任何東西都更爲典型。我正在探索將變量的範圍限制在三元語句內 - 不一定是我提供的確切代碼塊的最優化。這就是說,這絕對是值得回憶的一句話。 –

+0

好的,可能值得修改你的問題,用一些瑣碎的東西代替GetHashCode(),它掩蓋了你試圖達到的最優化。 – openshac

+0

這是一個公平點。我會這樣做的。 –

1

你可以代替具有在範圍數據變量(i)具有在範圍的函數的變量。優點是功能更可能只寫入一次而不可能被濫用。

int positiveHash(string param) 
{ 
    Func<int, int> absoluteValue = i => (i > 0) ? i : -1; 

    return absoluteValue(param.GetHashCode()); 
} 
+0

我對lambda表達式的使用經驗有限,但我喜歡這樣。我會更多地關注函數變量 - 謝謝。 –

0

除了剛剛創建一個新的模塊,你還可以使用內置的絕對值函數Math.Abs(...)或定義自己的λ/功能;

...建於...

public static int hash(string param) 
{ 
    return Math.Abs(param.GetHashCode()); 
} 

... ...拉姆達

static Func<int, int> abs = i => i > 0 ? i : -i; 
public static int hash(string param) 
{ 
    return abs(param.GetHashCode()); 
} 

...靜態函數...

static int Abs(int i) 
{ 
    return i > 0 ? i : -i; 
} 
public static int hash(string param) 
{ 
    return Abs(param.GetHashCode()); 
} 
0

和我嘗試

static int positiveHash(string param) 
{ 
    return new List<string>() {param}.Select(s => s.GetHashCode()).Select(i => (i > 0) ? (i) : (-i)).Single(); 
} 

(當然你的代碼(和我)是壞的,你需要給你的方法分爲2級較小的)

和更新的問題

static int absoluteValueOfOnePlus(int intparam) 
{ 
     return new List<int> { intparam }.Select(n => n + 1).Select(i => (i > 0) ? (i) : (-i)).Single(); 
}