switch()语句,带有string.contains()作为参数

Emi*_*son 2 c# dictionary if-statement switch-statement

我有点新手C#,我正在尝试创建一个switch返回int与给定文件名对应的ID()的方法.

例如:

var fileName = "file-example_MAP_COPY.xml";
var fileTypeId = GetFileTypeId(fileName); // Returns 3310
Run Code Online (Sandbox Code Playgroud)

GetFileTypeId方法看起来像这样:

private GetFileTypeId(string fileName)
{
    switch(string.Contains(fileName))
    {
        case ".xsd":
            return 3010;
        case "_Gui.xml":
            return 3120;
        case ".xml":
            return 3300;
        case "_MAP_COPY.xml":
            return 3310;
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我无法修剪实际的文件名,只保留扩展名,因为文件名可能包含下划线.如果在第一个下划线处修剪,则名称为" example_1_MAP_COPY.xml "的文件将被修剪为" _1_MAP_COPY.xml ",从而导致文件扩展名出错.

一个if声明可以在这里工作,但由于我有18个不同的情况,我想找到另一个解决方案,而不是写18个if语句.

有没有什么方法我可以去做这个,switch或许是用语句或字典?

Mar*_*ell 5

在当前的C#中,您可以执行以下操作:

switch(filename) {
    case string s when s.Contains(".xsd"): // or EndsWith, etc
         ...
}
Run Code Online (Sandbox Code Playgroud)

我并不是说这是最好的方法,也不是说它在if/上添加了任何东西else if,但是...有效。

在18条复杂case语句与18条if语句之间没有太多选择。除了该if方法不需要您在所有位置添加break;,而且不会在案例之间泄漏变量声明。

就个人而言,我将使用if/ else if-或匹配/结果对的静态数组:

static readonly (string Match, int Result)[] MatchResults = new[] {
    (".xsd", 3010),
    ("_Gui.xml", 3120),
    // ...
};

...

foreach(var pair in MatchResults) {
    if(filename.Contains(pair.Match)) return pair.Result;
}
Run Code Online (Sandbox Code Playgroud)


Pat*_*man 5

您可以使用switch确实,但似乎您只使用字符串的结尾,因此您可以使用其他列表类型来保存模式及其结果:

var l = new []
        { new { Pattern = ".xsd", Value = 3010 }
        , new { Pattern = "_MAP_COPY.xml", Value = 3310 }
        };

foreach (var p in l)
{
    if (filename.EndsWith(p.Pattern))
    {
        return p.Value;
    }
}

// not found
Run Code Online (Sandbox Code Playgroud)