2012-09-14 135 views
2

假設我有一個將整數作爲參數的函數。我希望能夠使用枚舉列表來保持整數值的組織。將枚舉值傳遞給函數

例如,我非常希望能夠來定義這些(僞):

public enum days 
{ 
    monday, 
    tuesday, 
    etc... 
} 

public enum months 
{ 
    january, 
    february, 
    etc... 
} 

int doSomething(enum x) 
{ 
    return x + 1; 
} 

,然後能夠調用使用任何所列舉的名單像這樣的功能:

int a = doSomething(days.monday); 
int y = doSomething(months.february); 

這顯然不會按原樣工作,因爲doSomething需要使用其中一個枚舉(即日或月)來定義。我知道一些選擇。一個是簡單地轉換爲int:

int a = doSomething((int)days.monday); 
int y = doSomething((int)months.february); 

與此唯一的問題是,這個函數被調用我的代碼中的許多地方,和它的笨拙不得不一直把「(INT)」一切都結束了(首先將這些int值組合到枚舉中的主要動機之一是使代碼更易讀)。

另一種選擇是避免枚舉完全,而是捆綁值到一個容器類,是這樣的:

static class Days 
{ 
    static int x = 0; 

    static int monday = x++; 
    static int tuesday = x++; 
} 

同樣,這將工作,但似乎只是非常繁瑣時,我有很多這樣的容器類來定義。

答案很可能是沒有簡單的方法,而且我需要成爲一名成年人並接受這些選項之一。但是我認爲在做出承諾之前我會對此進行理智的檢查。有第三種選擇嗎?

回答

2

你的問題是什麼?

public enum Days : short 
{ 
    Monday = 1, 
    Tuesday = 2, 
    ... 
} 

DoSomething(Days.Monday); 

void DoSomething(Days day) 
{ 
    Days nextDay = day + 1; 
} 

另請注意already built-in enum System.DayOfWeek


我得到了OP的觀點,但據我所知,這是不是C#還支持:

void DoSomething<T>(T e) where T : enum 
{ 
    T next = e + 1; 
} 
+0

WRT的System.DayOfWeek,我使用的月份和日期值只是一個例子。在真正的應用程序中,它們完全不相關的日子或時間。對於你顯示的代碼,DoSomething()函數只能在Days enum上運行。如果我嘗試提供不同的枚舉,它將失敗。 – Gadzooks34

+0

@ Gadzooks34:我明白你的觀點。但不幸的是C#不支持枚舉的通用約束。請參閱我更新的帖子以獲取描述 – abatishchev

0

是的,你可以這樣做

public enum days : int 
{ 
    monday, 
    tuesday, 
    ... 
} 

自動週一變爲0,週二變爲1等on

public enum months : int 
{ 
    january, 
    february, 
    ... 
} 

同幾個月

int doSomething(Enum x) 
{ 
    return (int)x + 1; 
} 

,並把它作爲

int a = doSomething(days.monday); 

或現在稱其爲

int a = doSomething(months.january); 

days.monday equals 0之後方法a變爲1

+1

這看起來不錯,但它不起作用。編譯器會抱怨doSomething()的參數無效,即使枚舉是從int派生的。 – Gadzooks34

+0

@ Gadzooks34:現在怎麼樣? –

+0

那麼,這回到我的例子。是的,在函數中轉換爲int可以工作,它只是比我想的要笨拙。 – Gadzooks34

0

System.DateTime什麼問題嗎?

這將是最實用的類型使用。

+0

我只使用這些值作爲示例。它們在實際應用中實際上並不涉及日期/時間。 – Gadzooks34

0

你可以重載你的方法,如果你真的只想要int值,也許這樣?

int dosomething(enum x) 
{return dosomething((int)x)} 
int dosomething(int x) 
{return x+1} 
+0

我嘗試過,但我不認爲你可以實際定義這樣的功能。定義doSomething(枚舉x)期望整個枚舉被傳遞,而不僅僅是它的一個值,這不是我想要的(對不起,如果我的僞代碼不清楚)。 – Gadzooks34

+0

對不起,我試圖建議的是,每個枚舉都有一個超載,例如, 'dosomething(days x)''dosomething(months x)'問題是,如果你有很多不同的枚舉,這可能會變得很大。 – Sconibulus

+0

是的。問題在於函數是在基本庫中定義的,然後用戶將定義自己的枚舉而不訪問該函數的源代碼。 – Gadzooks34

0

或者,如果你不想改變現有的所有枚舉:

public static int DoSomething(Enum x) 
    { 
     int xInt = (int)Convert.ChangeType(x, x.GetTypeCode()); 
     DoSomething(xInt); 
    } 

如下陳述:enums-returning-int-value

+0

這是一個非常酷的伎倆。我認爲這將起作用。我唯一擔心的是表現(儘管我沒有在我的問題中提到這一點)。看起來像轉換可能會很慢:[更快的Convert.ChangeType版本](http://stackoverflow.com/questions/1532197/faster-version-of-convert-changetype) – Gadzooks34

+0

好,如果運行時性能更重要我會建議一些仿製藥,昂貴的地方,但更好的表現。 –

0

你嘗試通過參數重載函數:

int DoSomething(Enum1 value) 
int DoSomething(Enum2 value) 
+0

請參閱我對Sconibulus的回覆。 – Gadzooks34

0
public enum days : int 
{ monday, tuesday, 

} 

public enum months :int 
{ january, february, march, 

} 

public int doSomething(int z) 
{ 
    return z + 1; 
} 

//你的調用方法int c = ee.doSomething((int)testenums.months.march); int c = ee.doSomething((int)testenums.day.February);

工作代碼爲你總是通過枚舉和這類型的詮釋,你只需要解析和發送該代碼的完美的作品..讓我知道

+0

我相信如果你複製並粘貼你的代碼到IDE你會發現它不起作用,而是產生我所描述的問題(函數doSomething()參數是無效類型)。 – Gadzooks34

+0

爲什麼它不會工作..它是一個工作代碼,你爲什麼會返回一個無效的參數類型..你只需要看看它。 int c = ee.doSomething((int)testenums.months.march),檢查你的枚舉類型是短還是int – Praveen

0

我花在這個「小」的時候,因爲有一個同樣的問題(解決方案)。 因此,這裏是我的解決方案,它在(.NET 4)做工精細,Windows窗體:

VB:NET 

      Private Function DoSomething(Of TEnum As {IComparable, IConvertible, IFormattable})(ByVal valueEnum As TEnum) As Int32 

       Dim i As Int32 = CInt(Convert.ChangeType(valueEnum, valueEnum.GetTypeCode())) 
       //Do something with int 
       i += 1 
       Return i 

      End Function 

    C# 

     private int DoSomething<TEnum>(TEnum valueEnum) where TEnum: IComparable, IConvertible, IFormattable 
        { 
         int i = 0; 
         i = (int)Convert.ChangeType(valueEnum, valueEnum.GetTypeCode()); 
         i++; 
         return i; 
        }