Переключить PropertyType - PullRequest
       16

Переключить PropertyType

27 голосов
/ 18 сентября 2008

Как мне сделать эту работу?

switch(property.PropertyType){
    case typeof(Boolean): 
        //doStuff
        break;
    case typeof(String): 
        //doOtherStuff
        break;
    default: break;
}

Я не хочу использовать имя, так как сравнение строк для типов просто ужасно и может быть изменено.

Ответы [ 10 ]

43 голосов
/ 18 сентября 2008
        System.Type propertyType = typeof(Boolean);
        System.TypeCode typeCode = Type.GetTypeCode(propertyType);
        switch (typeCode)
        {
            case TypeCode.Boolean:
                //doStuff
                break;
            case TypeCode.String:
                //doOtherStuff
                break;
            default: break;
        }

Вы можете использовать гибридный подход для TypeCode.Object, где вы динамически работаете с typeof. Это очень быстро, потому что для первой части - переключателя - компилятор может принять решение на основе таблицы поиска.

3 голосов
/ 18 сентября 2008

Вы не можете. Что вы можете сделать, это создать отображение между типами и делегатом, используя словарь:

var TypeMapping = new Dictionary<Type, Action<string>>(){
    {typeof(string), (x)=>Console.WriteLine("string")},
    {typeof(bool), (x)=>Console.WriteLine("bool")}
};



string s = "my string";

TypeMapping[s.GetType()]("foo");
TypeMapping[true.GetType()]("true");
2 голосов
/ 18 сентября 2008

Я думаю, что вы ищете здесь хорошую карту. Используя делегатов и общий IDictionary, вы можете делать то, что вы хотите.

Попробуйте что-то вроде этого:

private delegate object MyDelegate();

private IDictionary<Type, MyDelegate> functionMap = new IDictionary<Type, MyDelegate>();

public Init()
{
  functionMap.Add(typeof(String), someFunction);
  functionMap.Add(tyepof(Boolean), someOtherFunction);
}

public T doStuff<T>(Type someType)
{
   return (T)functionMap[someType]();
}
1 голос
/ 11 декабря 2016

C # 7.0 будет поддерживать переключение типов как часть большей функции сопоставления с образцом. Этот пример взят из .NET-блога , в котором объявляются новые функции:

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));
}
1 голос
/ 18 сентября 2008

Я лично предпочитаю подход Dictionary<Type, other> больше всего ... Могу даже привести другой пример: http://www.timvw.be/presenting-namevaluecollectionhelper/

Если вы настаиваете на написании оператора switch-case, вы можете использовать имя типа ...

switch (blah.PropertyType.FullName)
{
   case typeof(int).FullName: break;
   case typeof(string).FullName: break;
}
0 голосов
/ 18 сентября 2008

О сопоставлении строк: это был один из вопросов в вопросе, чтобы не делать это через сопоставление строк.

Словарь - это подход, который я буду использовать, когда помещу весь этот алгоритм сериализации в свою собственную библиотеку. На данный момент я сначала попробую typeCode, так как в моем случае используются только базовые типы. Если это не сработает, я вернусь к рой if / elses: S

Перед тем, как ppl спросит меня, почему я хочу свою собственную сериализацию: 1) сериализация .net xml не сериализует свойства без установщиков 2) сериализация должна соответствовать некоторым устаревшим правилам

0 голосов
/ 18 сентября 2008

Мне недавно пришлось сделать что-то подобное, и использование переключателя было невозможно. Выполнение == для typeof (x) - это хорошо, но более элегантный способ - сделать что-то вроде этого:

if(property.PropertyType is bool){
  //dostuff;
}
else if (property.PropertyType is string){
    //do other stuff;
}

Но я не уверен, что вы можете использовать ключевое слово "is" таким образом, я думаю, что это работает только для объектов ...

0 голосов
/ 18 сентября 2008

Просто используйте обычный шаблон if / else if / else:

if (property.PropertyType == typeof(Boolean))
{
} 
else if (property.PropertyType == typeof(String))
{
}
else if (...)
{
}
0 голосов
/ 18 сентября 2008

Вы не можете сделать это с помощью switch в c #, так как регистр должен быть постоянным.

Что не так с:

if(property.PropertyType == typeof(bool)) {
    //dostuff;
}
else if (property.PropertyType == typeof(string)) {
    //do other stuff;
}
0 голосов
/ 18 сентября 2008

Не беспокойтесь об использовании строк в коммутаторе, потому что если у вас их несколько, компилятор автоматически преобразует их в хеш-поиск, обеспечивающий приличную производительность, несмотря на то, что выглядит довольно ужасно.

Проблему изменения строк типов можно решить, превратив ее в явный поиск хеша и заполнив содержимое хеша в статическом конструкторе. Таким образом, хэш заполняется правильными строками во время выполнения, поэтому они остаются правильными.

...