簡體   English   中英

C#切換類型

[英]C# switch with types

編輯: 現在可以在C#7.0中使用。


我有以下代碼檢查給定的PropertyInfotype

PropertyInfo prop;

// init prop, etc...

if (typeof(String).IsAssignableFrom(prop.PropertyType)) {
    // ...
}
else if (typeof(Int32).IsAssignableFrom(prop.PropertyType)) {
    // ...
}
else if (typeof(DateTime).IsAssignableFrom(prop.PropertyType)) {
    // ...
}

有沒有辦法在這種情況下使用switch語句? 這是我目前的解決方案:

switch (prop.PropertyType.ToString()) {
    case "System.String":
        // ...
        break;
    case "System.Int32":
        // ...
        break;
    case "System.DateTime":
        // ...
        break;
    default:
        // ...
        break;
}

我不認為這是最好的解決方案,因為現在我必須給出給定type的完全限定的String值。 有小費嗎?

現在可以在C#7.0中使用它。

這個解決方案適合我原來的問題; switch語句處理PropertyInfovalue而不是PropertyType

PropertyInfo prop;

// init prop, etc...

var value = prop.GetValue(null);

switch (value)
{
    case string s:
        // ...
        break;
    case int i:
        // ...
        break;
    case DateTime d:
        // ...
        break;
    default:
        // ...
        break;
}

稍微更通用的答案:

switch(shape)
{
    case Circle c:
        WriteLine($"circle with radius {c.Radius}");
        break;
    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} square");
        break;
    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} rectangle");
        break;
    default:
        WriteLine("<unknown shape>");
        break;
    case null:
        throw new ArgumentNullException(nameof(shape));
}

參考: https//blogs.msdn.microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

我將完全按照要求回答這個問題:沒有辦法。

從C#6 switch只支持精確匹配某些類型的常量。 你不是試圖匹配常數。 您多次調用IsAssignableFrom方法。

注意, IsAssignableFrom相同的精確匹配的類型。 因此,任何基於相等比較或哈希表的解決方案都無法工作。

我認為if ... else if你擁有的解決方案完全沒問題。

沒有通用的方法,但更常見的是,這些分支包含非常相似的代碼。 幾乎總是對我有用的一種模式是使用字典;

var myIndex = new Dictionary<Type, string> {
    { typeof(string), "some text" },    
    { typeof(int), "a whole number" },    
    { typeof(decimal), "a fraction" },    
};

string description;
if (myIndex.TryGetValue(prop.PropertyType, out description)) {
    Console.WriteLine("This type is " + description);
} else {
    // 'default'
}

使用你擁有的ToString方法,但不是文字值使用case typeof(string).Name(如果可能的話)現在沒有vs在我面前。

首先, IsAssignableFrom比繼承類型的字符串比較更好。 例如typeof(TextReader).IsAssignableFrom(typeof(StreamReader))將為true ,因為StreamReader繼承自TextReader ,也適用於接口。

如果您只需要直接比較,我可以建議創建Dictionary<Type,Action<PropertyInfo>> ,例如:

var typeSelector = new Dictionary<Type, Action<PropertyInfo>>()
{
    {typeof(int), IntAction }
    {typeof(string), StringAction }
    {typeof(DateTime), DateTimeAction }
};

然后你可以像這樣使用它:

Action<PropertyInfo> action;
if (typeSelector.TryGetValue(prop.PropertyType, out action))
    action(prop);
else 
    throw new InvalidDataException("Unsupported type");

在這種情況下,您必須為每種類型創建方法,或在創建字典期間編寫代碼。

如MårtenWikström的回答所示:“ 如何在Type上使用switch-case? ”你可以使用Type.GetTypeCode

switch (Type.GetTypeCode(type))
{
    case TypeCode.Int32:
       // It's an int
    break;

    case TypeCode.String:
       // It's a string
    break;

    // Other type code cases here...

    default:
        // Fallback to using if-else statements...
        if (type == typeof(MyCoolType))
        {
           // ...
        }
        else if (type == typeof(MyOtherType))
        {
           // ...
    } // etc...
}

暫無
暫無

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

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