私が使用しているC#アプリをやっています
_if ((message.Contains("test")))
{
Console.WriteLine("yes");
} else if ((message.Contains("test2"))) {
Console.WriteLine("yes for test2");
}
_
switch()
if()
ステートメントに変更する方法はありますか?
最初にチェックを行ってから、必要に応じてスイッチを使用できます。
例えば:
string str = "parameter"; // test1..test2..test3....
if (!message.Contains(str)) return ;
それから
switch(str)
{
case "test1" : {} break;
case "test2" : {} break;
default : {} break;
}
いいえ、switchステートメントにはコンパイル時定数が必要です。ステートメントmessage.Contains("test")
はメッセージに応じてtrueまたはfalseを評価できるため、定数ではないため、switchステートメントの「ケース」として使用できません。
switch/case
のみを使用する場合は、次のような擬似コードを実行できます。
string message = "test of mine";
string[] keys = new string[] {"test2", "test" };
string sKeyResult = keys.FirstOrDefault<string>(s=>message.Contains(s));
switch (sKeyResult)
{
case "test":
Console.WriteLine("yes for test");
break;
case "test2":
Console.WriteLine("yes for test2");
break;
}
ただし、キーの数が多い場合は、次のように辞書に置き換えることができます。
static Dictionary<string, string> dict = new Dictionary<string, string>();
static void Main(string[] args)
{
string message = "test of mine";
// this happens only once, during initialization, this is just sample code
dict.Add("test", "yes");
dict.Add("test2", "yes2");
string sKeyResult = dict.Keys.FirstOrDefault<string>(s=>message.Contains(s));
Console.WriteLine(dict[sKeyResult]); //or `TryGetValue`...
}
[Mr. C]の答え。
VS2017RCのリリースとそのC#7サポートにより、次のように機能します。
switch(message)
{
case string a when a.Contains("test2"): return "no";
case string b when b.Contains("test"): return "yes";
}
最初の一致が選択されるため、ケースの順序に注意する必要があります。そのため、テストの前に「test2」が配置されます。
これはC#7で動作します。この記事の執筆時点では、まだリリースされていません。しかし、これを正しく理解すれば、このコードは機能します。
switch(message)
{
case Contains("test"):
Console.WriteLine("yes");
break;
case Contains("test2"):
Console.WriteLine("yes for test2");
break;
default:
Console.WriteLine("No matches found!");
}
ソース: https://blogs.msdn.Microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/
このようにカスタムswtichを作成できます。複数のケースの実行も可能にします
public class ContainsSwitch
{
List<ContainsSwitch> actionList = new List<ContainsSwitch>();
public string Value { get; set; }
public Action Action { get; set; }
public bool SingleCaseExecution { get; set; }
public void Perform( string target)
{
foreach (ContainsSwitch act in actionList)
{
if (target.Contains(act.Value))
{
act.Action();
if(SingleCaseExecution)
break;
}
}
}
public void AddCase(string value, Action act)
{
actionList.Add(new ContainsSwitch() { Action = act, Value = value });
}
}
このような呼び出し
string m = "abc";
ContainsSwitch switchAction = new ContainsSwitch();
switchAction.SingleCaseExecution = true;
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });
switchAction.AddCase("d", delegate() { Console.WriteLine("matched d"); });
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });
switchAction.Perform(m);
環境を決定するときにこの問題に直面して、私は次のワンライナーを思いつきました:
string ActiveEnvironment = localEnv.Contains("LIVE") ? "LIVE" : (localEnv.Contains("TEST") ? "TEST" : (localEnv.Contains("LOCAL") ? "LOCAL" : null));
そのようにして、提供された文字列で「スイッチ」条件に一致するものが見つからない場合、null
を放棄して返します。これは、異なる値を返すように簡単に修正できます。
厳密にはスイッチではなく、カスケードifステートメントですが、きちんと機能します。
string message = "This is test1";
string[] switchStrings = { "TEST1", "TEST2" };
switch (switchStrings.FirstOrDefault<string>(s => message.ToUpper().Contains(s)))
{
case "TEST1":
//Do work
break;
case "TEST2":
//Do work
break;
default:
//Do work
break;
}