Использование строк вместо перечислений? - PullRequest
1 голос
/ 12 января 2011

Распространено ли использование строки для сравнения, а не перечисления?

Ответы [ 6 ]

7 голосов
/ 12 января 2011

Я знаю о вашем контексте, но в качестве первого шага вы можете просто изменить рефакторинг следующим образом:

Шаг 1

if (typeOfObject == "UAV")
{
    DoSomeWork(_stkObjectRootToIsolateForUavs);
}
else if (typeOfObject == "Entity")
{
    DoSomeWork(_stkObjectRootToIsolateForEntities);
}

private void DoSomeWork(IAgStkObject agStkObject)
{
    IAgStkObject stkObject = agStkObject.CurrentScenario.Children[stkObjectName];
    IAgDataProviderGroup group = (IAgDataProviderGroup)stkUavObject.DataProviders["Heading"];
    IAgDataProvider provider = (IAgDataProvider)group.Group["Fixed"];
    IAgDrResult result = ((IAgDataPrvTimeVar)provider).ExecSingle(_stkObjectRootToIsolateForUavs.CurrentTime);

    stkObjectHeadingAndVelocity[0] = (double)result.DataSets[1].GetValues().GetValue(0);
    stkObjectHeadingAndVelocity[1] = (double)result.DataSets[4].GetValues().GetValue(0);
}

Затем рассмотрите возможность замены if напереключатель:

Шаг 2

switch (typeOfObject)
{
    case "UAV":
        DoSomeWork(_stkObjectRootToIsolateForUavs);
        break; 
    case "Entity":
        DoSomeWork(_stkObjectRootToIsolateForEntities);
        break;
    default:
        throw new NotImplementedException():
}

Это может быть даже лучше при использовании перечислений.

3 голосов
/ 12 января 2011

Чтобы добавить ответ @ Restuta, я бы использовал

IDictionary<MyEnumifiedString, Action<IAgStkObject>> 

чтобы избавиться от этого, если.

3 голосов
/ 12 января 2011

По крайней мере, строки должны быть объявлены как константы (или, возможно, readonly поля) где-то, а не распространяться через код.Тем не менее, это похоже на пример из учебника о том, когда использовать enum.

public enum ObjectType
{
   UAV,
   Entity,
   // and so on
}
0 голосов
/ 12 января 2011

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

Так что для вашего примера у меня будет следующее

public sealed class RootTypes
{
    public const string Entity = "entity";
    public const string UAV = "uav";
}

Ваш код обновится до этого

    typeOfObject = typeOfObject.ToLower();
    if (typeOfObject == RootTypes.UAV)
    {
        stkUavObject = _stkObjectRootToIsolateForUavs.CurrentScenario.Children[stkObjectName];
        var group = (IAgDataProviderGroup) stkUavObject.DataProviders["Heading"];
        var provider = (IAgDataProvider) group.Group["Fixed"];
        IAgDrResult result = ((IAgDataPrvTimeVar) provider).ExecSingle(_stkObjectRootToIsolateForUavs.CurrentTime);
        stkObjectHeadingAndVelocity[0] = (double) result.DataSets[1].GetValues().GetValue(0);
        stkObjectHeadingAndVelocity[1] = (double) result.DataSets[4].GetValues().GetValue(0);
    }
    else if (typeOfObject == RootTypes.Entity)
    {
        IAgStkObject stkEntityObject = _stkObjectRootToIsolateForEntities.CurrentScenario.Children[stkObjectName];
        var group = (IAgDataProviderGroup) stkEntityObject.DataProviders["Heading"];
        var provider = (IAgDataProvider) group.Group["Fixed"];
        IAgDrResult result = ((IAgDataPrvTimeVar) provider).ExecSingle(_stkObjectRootToIsolateForEntities.CurrentTime);
        stkObjectHeadingAndVelocity[0] = (double) result.DataSets[1].GetValues().GetValue(0);
        stkObjectHeadingAndVelocity[1] = (double) result.DataSets[4].GetValues().GetValue(0);
    }

Проблема избыточности кода была решена Restuta

0 голосов
/ 12 января 2011

Используйте перечисления с битовыми флагами:

[Flags]
public enum MyFlags
{
    SomeFlag = 0x1, // 001
    OtherFlag = 0x2,// 010
    ThirdFlag = 0x4 // 100
}

var firstObject = MyFlags.SomeFlag;
var secondObject = MyFlags.SomeFlag | MyFlags.OtherFlag;

if(((int)secondObject & MyFlags.SomeFlag) != 0) 
{
    // true
}

if(((int)secondObject & MyFlags.OtherFlag) != 0) 
{
    // true
}

if(((int)firstObject & MyFlags.SomeFlag) != 0) 
{
    // true
}

if(((int)firstObject & MyFlags.OtherFlag) != 0) 
{
    // false
}

Эта статья будет полезна.

0 голосов
/ 12 января 2011

Я бы согласился с @Frederik, что это кажется идеальным вариантом для использования перечислений, но может случиться так, что единственное, что вы можете получить из приложения - это строка.В этом случае ваш пример совершенно нормален.

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

...