列挙型ではなく、比較のために文字列を使用するのが一般的な場所ですか?
6 に答える
私はあなたのコンテキストを知っていますが、最初のステップとして、次のようにリファクタリングすることができます。
ステップ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);
}
次に、スイッチを使用している場合は、次のように言い換えることを検討してください。
ステップ2
switch (typeOfObject)
{
case "UAV":
DoSomeWork(_stkObjectRootToIsolateForUavs);
break;
case "Entity":
DoSomeWork(_stkObjectRootToIsolateForEntities);
break;
default:
throw new NotImplementedException():
}
これは、列挙型を使用する場合にさらに改善される可能性があります。
少なくとも、文字列はreadonly
、コード全体に広がるのではなく、どこかで定数(またはおそらくフィールド)として宣言する必要があります。ただし、これは、を使用する場合の教科書の例のように見えますenum
。
public enum ObjectType
{
UAV,
Entity,
// and so on
}
@Restutaの答えに追加するには、
IDictionary<MyEnumifiedString, Action<IAgStkObject>>
もしそうならそれを取り除くために。
これは列挙型を使用するのに最適なケースのように思われるという@Frederikに同意しますが、アプリケーションから取得できるのは文字列だけである可能性があります。その場合、あなたの例は完全にOKです。
そうです-そして、文字列定数が1つの場所、できれば構成ファイルで定義されていることを確認してください。そうすれば、他のアプリケーションが変更された場合でも、再コンパイルする必要がありません。
最初の質問に関しては、必要に応じて変更する場所を1つにするために、常に定義済みの型を使用して文字列を格納します。
だからあなたの例のために私は次のようになります
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によって解決されました
ビットフラグ付きの列挙型を使用します。
[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
}
この記事は役に立ちます。