2013-10-01 121 views
0

我寫了採用可選參數可選參數和默認值

public void ExampleMethod(int maxValue = 20) 
{ 
    ... 
} 

,如果小於20,我將用它作爲

int param = GetSomeValue(); 
ExampleMethod(param < 20 ? param : use_your_default_value_as_specified); 

,使用PARAM,否則使用自己的方法在ExampleMethod中實現的默認值(在這個例子中是20)。我如何告訴「use_your_default_value_as_specified」編譯器?

我知道我可以通過

int param = GetSomeValue(); 
ExampleMethod(param); 

public void ExampleMethod(int maxValue) 
{ 
    if(maxValue > 20) 
     maxValue = 20; 
} 

做到這一點,但我想ExampleMethod

回答

0

這是有點尷尬,但它確實允許您檢索默認參數。一旦你有了價值,你可以將它與我上面的答案結合起來,以獲得你想要去的地方。

這是LINQPad格式。

void Main() 
{ 
    Console.WriteLine(AddEm()); 

    Console.WriteLine("Default for parm1 is " + GetDefaultParm<int> (GetType().GetMethod("AddEm"), "parm1")); 
    Console.WriteLine("Default for parm2 is " + GetDefaultParm<int>(GetType().GetMethod("AddEm"), "parm2")); 
    Console.WriteLine("Default for parm3 is " + GetDefaultParm<int>(GetType().GetMethod("AddEm"), "parm3")); 
} 

private T GetDefaultParm<T>(MethodInfo m, string parmname) { 
    var parm = m.GetParameters().Where(p => p.Name == parmname).FirstOrDefault(); 
    if (parm != null) { 
     return (T) parm.DefaultValue; 
    } 
    throw new Exception("Parameter not found."); 
} 


// Define other methods and classes here 
public int AddEm(int parm1 = 10, int parm2 = 20, int parm3 = 30) { 
    return parm1 + parm2 + parm3; 
} 

輸出:

60 
Default for parm1 is 10 
Default for parm2 is 20 
Default for parm3 is 30 
1

執行之前發送正確的值告訴編譯使用默認值的唯一途徑參數不是完全指定它。

你可以使用一些反射kludgery在運行時獲得的價值:

public static object DefaultValueForParameter(Type type, string methodName, int parameterNumber) 
{ 
    return type.GetMethod(methodName).GetParameters()[parameterNumber].DefaultValue; 
} 

ExampleMethod(param < 20 ? param : (int)DefaultValueForParameter(this.GetType(), "ExampleMethod", 0)); 

但是,這不是很優雅和高效。

您可以重構ExampleMethod採取爲空的參數,而不是像這樣:

public void ExampleMethod(int? maxValue = null) 
{ 
    if(maxValue.HasValue) 
     maxValue = 20; 
} 

ExampleMethod(param < 20 ? (int?)param : null); 

這樣,在實際默認值的函數中隱藏。本身,我知道這看起來很像你說你不想使用的代碼,但有一個關鍵的區別。它將可以傳入的值的邏輯與默認值應該是什麼分開。在你說你不想使用的解決方案中,不可能將10作爲maxValue,因爲它會在你的方法中被覆蓋。

你也可以重構這使得默認值是一個公開的常量,像這樣:

const int DefaultMaxValue = 20; 

public void ExampleMethod(int? maxValue = DefaultMaxValue) 
{ 
    maxValue.Dump(); 
} 

ExampleMethod(param < 20 ? param : DefaultMaxValue); 

這樣一來,你有,你可以在多個地方使用默認值的好處你的代碼無需每次都指定它。


不過,如果你不喜歡上面的任何解決方案,你可以堅持最簡單的方法。我知道這不是正是你要找的,但我可能會與此去:

if (param < 20) 
    ExampleMethod(param) 
else 
    ExampleMethod(); 

還要注意的是,如果ExampleMethod返回之外的東西比void,你可以這樣做:

var result = param < 20 ? ExampleMethod(param) : ExampleMethod(); 
+0

其實在我的項目有6-7可選參數。所以我不能像這樣使用它 – Melih

+1

@Melih:這是一個大問題,應該是在問題。 –

+0

其實根據我的問題,我需要知道我是否可以對編譯器說「使用方法中指定的任何默認值」 – Melih

0

你可以做一堂課嗎?

// Individual Parameter Values 
class ParameterValueClass { 
    double _Value; 
    double _Max; 
    public double Value { get { return (_Value < _Max) ? _Value : _Max } 
         set { _Value = value; } } 
    public ParameterValueClass(Max) { _Max = Max; } 
} 
// Set of Parameter Values 
class ParameterSetClass { 
     public ParameterValueClass Parameter1; 
     public ParameterValueClass Parameter2; 
     public ParameterValueClass Parameter3; 
     public ParameterSetClass() { 
      Parameter1 = new ParameterValueClass(20); 
      Parameter2 = new ParameterValueClass(4.22314); 
      Parameter3 = new ParameterValueClass(700000); 
     } 
} 

void ExampleMethod(ParameterSetClass Parameters) { 
    /// Parameter1.Value returns the Value or "Max" value. Could also use a min value. 

    } 
0

您可以隨時使用反射。參數集合中的示例代碼包含一個具有默認值的參數列表。每個參數都有屬性DefaultValue及其默認值。

private void Calc(int i, int j, int k = 60, int l = 80) 
    { 
     var parameters = 
      System.Reflection.MethodInfo.GetCurrentMethod().GetParameters().Where(param => param.HasDefaultValue); 
     //parameters = {k, l} 

    } 
0

通過你的最後一句話,我假設你想要的參數,這樣你居然要去當你進入ExampleMethod()使用的值。你可能會嘗試的一件事是創建另一個對象或靜態方法來爲你計算出這個值。

class Helper { 
    public static int MakeParam(int myParam) { 
     return myParam < 20 ? myParam : use_your_default_value_as_specified; 
    } 
} 
... 
ExampleMethod(Helper.MakeParam(17)); 

這使您可以對該方法外部的參數執行任何邏輯。如果你需要它,你甚至可以有一個版本,它允許您在您的默認值傳遞:

class Helper { 
    public static int MakeParam(int myParam) { 
     return MakeParam(myParam, use_your_default_value_as_specified); 
    } 
    public static int MakeParam(int myParam, int myDefault) { 
     return myParam < 20 ? myParam : myDefault; 
    } 
} 

那麼你可以使用命名參數僅供您要使用的那些提供值:

void Main() 
{ 
    Console.WriteLine(AddEm(parm3:50)); // = 80 
    Console.WriteLine(AddEm(parm2:50)); // = 90 
    Console.WriteLine(AddEm());   // = 60) 
} 

public int AddEm(int parm1 = 10, int parm2 = 20, int parm3 = 30) { 
    return parm1 + parm2 + parm3; 
} 

祝你好運!

+0

其實,我不知道「use_your_default_value_as_specified」。在這種情況下,它是可選參數缺省值的複製。例如,我有6-7 opt參數,當我調用ExampleMethod時,我將發送參數「if ... use ...,否則使用您自己的默認值」 – Melih

0

您可以創建一個方法,只需執行檢查並將要使用的正確值分配給var即可。 (相對於默認值)。 然後,在你讓6-7選中變量後,調用該方法並提供這些變量。