簡體   English   中英

如何在C#中使用泛型聲明的變量

[英]How to use generic declared variable in C#

public static object GetObject(int x)
{
    return new object { };
}
public static object GetObject(string x)
{
    return new object { };
}
public static void ProcessObject<T>(T x) where T : int, string <= got error here: 
{
    object o = GetObject(x);
}

得到錯誤“用作約束的類型必須是接口,未密封的類或類型參數。”

我如何重寫代碼以使其工作而無需兩次編寫ProcessObject(int x)ProcessObject(string x)

因此,您現在所擁有的(根據公認的答案和您的評論)是:

public static void ProcessObject<T>(T x)
{
    object o;
    if (typeof(T) == typeof(int))
        o = GetObject((int)(object)x);
    else if (typeof(T) == typeof(string))
        o = GetObject((string)(object)x);
    else
        throw new Exception();
    // do stuff with o
}

我建議公開intstring重載,但是為了防止代碼重復,請在內部調用另一個方法:

public static void ProcessObject(int x)
{
    ProcessObject(GetObject(x));
}
public static void ProcessObject(string x)
{
    ProcessObject(GetObject(x));
}
private static void ProcessObject(object o)
{
    // do stuff with o
}

這使您的public方法的輸入值更加清晰: intstring是唯一可接受的類型,同時仍然不會重復您的實際邏輯( // do stuff with o )。

您可能不喜歡這兩個公共ProcessObject方法是彼此重復的(無論如何在表面上;在幕后,它們都在調用兩個不同的GetObject重載),但是我認為這是最好的選擇。

您無法做您想做的事情:首先, 不可能在通用約束中列出幾個類 第二,可以放入約束的類型必須能夠繼承(或在接口的情況下實現)。 intstring均未通過此檢查。 在這種情況下,最好使用兩個單獨的重載。

只需刪除where部分

public static void ProcessObject<T>(T x) 
{
    object o = GetObject(x);
}

並且不要在其他方法中使用object ,而應使用T

在C#中不可能查看類型參數的約束 嘗試使用動態

一般來說,如果您的對象根據泛型類型參數做出不同的反應,則在這種情況下,您可能不應該使用泛型。 無論您使用什么實際類型,泛型都非常適合您想要總是做同一件事的情況。

因此,通用約束將只允許您為類型參數列出一個基類。 從您指定的基類開始,傳遞給各個類型實參的任何實際類型都應成為給定繼承層次結構的一部分,因此,該類的用戶可以指定與該基類或其子類匹配的任何類型。

同時,您(泛型類的作者)可以安全地假定指定的類型具有(至少)約束所指示的基類的接口。 因此,您可以訪問基類的任何成員。

如果要允許使用stringint ,請想象可能是什么成員。 兩者都是直接從System.Object派生的,因此限制沒有意義,因為它不是限制。 每個類型都派生自System.Object

總結一下,如果您真的想以不同的方式對待stringint ,那么絕對可以提供兩個重載而不是一個泛型類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM