【问题标题】:What is the proper way to return two char arrays as a single string?将两个 char 数组作为单个字符串返回的正确方法是什么?
【发布时间】:2013-01-06 20:40:43
【问题描述】:

我在一个静态类中有一个公共属性,我想用它来验证用户输入的非法文件和路径名。

目前我有这个:

private static string invalidFileNames = new string(Path.GetInvalidFileNameChars());

private static string invalidPathNames = new string(Path.GetInvalidPathChars());

private static string invalidUserInput = (invalidFileNames + invalidPathNames); 

public static string InvalidUserInput
{

    get { return invalidUserInput; }

}

基于 Microsoft 的文档 here 我期待回复 "<>|"<>| 但我得到的只是第一个 "<>|

谁能解释一下这里发生了什么?如何确保返回两个字符串?

【问题讨论】:

  • 就诊断问题而言,您尝试了哪些方法?您是否考虑过分别返回两个组件字符串以确保它们包含您认为它们应该包含的内容?
  • InvalidUserInput 分配给一个变量似乎为我返回了正确的值。
  • @David - 如果我注释掉两个 char 数组并用“string a”和“string b”替换它们,我会按预期返回字符串 a 和字符串 b(stringastringb),但是,如果我使用private static string invalidPathNames = "string b" 我得到的只是 "|

标签: c# string properties path char


【解决方案1】:

你可以把它变成一个字符串

using System.Linq;

public static string InvalidUserInput
{
    get 
    {
        return new string(Path.GetInvalidFileNameChars()
                  .Concat(Path.GetInvalidPathChars())
                  .Distinct()
                  .ToArray());
    }
}

由于 InvalidUserInput 中的终止符类型字符,您不会在 TextBox 中看到它们,在您的情况下,它是停止显示的 \0(null 终止符)。

如果您只想显示对用户有意义的内容,您可以使用 Char.IsControl 删除导致问题的内容

这是一个静态类来包装它

public static class StringExtentions
{
    private static string _invalidUserInput = string.Empty;
    private static string _PrinatbleInvalidUserInput = string.Empty;

    public static string InvalidUserInput
    {
        get
        {
            if (_invalidUserInput == string.Empty)
            {
                _invalidUserInput = new string(Path.GetInvalidFileNameChars()
                      .Concat(Path.GetInvalidPathChars())
                      .Distinct()
                      .ToArray());
            }
            return _invalidUserInput;
        }
    }

    public static string GetPrinatbleInvalidUserInput
    {
        get
        {
            if (_PrinatbleInvalidUserInput == string.Empty)
            {
                _PrinatbleInvalidUserInput = new string(InvalidUserInput.Where(x => !char.IsControl(x)).ToArray());
            }
            return _PrinatbleInvalidUserInput;
        }
    }

    public static bool IsValidUserInput(this string str)
    {
        return !str.Any(c => InvalidUserInput.Contains(c));
    }
}

用法:

public MainWindow()
{
    InitializeComponent();
    string myString = "C:\\InvalidPath<";

    if (!myString.IsValidUserInput())
    {
        MessageBox.Show(string.Format("String cannot contain {0}", StringExtentions.GetPrinatbleInvalidUserInput));
    }
}

【讨论】:

  • 我喜欢这个建议,但 .Concat 位给了我以下错误 - 'System.Array' 不包含 'Concat' 的定义,并且没有扩展方法 'Concat' 接受第一个参数可以找到“System.Array”类型的(您是否缺少 using 指令或程序集引用?我在源代码的顶部有 using System;。
  • 感谢 sa_ddam213,使用 System.Linq 已解决该错误。出于测试目的,我将返回的字符串输出到文本框,但我仍然只看到“| 。
  • 您希望看到什么? TextBox 永远不会显示像 `\a\b\t\n\v\f` 这样的字符
  • 很公平,但是如果我将“这个字符串”附加到私有静态字符串 invalidFileNames = new string(Path.GetInvalidFileNameChars()); ,为什么不会与“|”一起返回?
  • 因为在“|”之后是终止字符串的“\0”。有关详细信息,请参见此处:msdn.microsoft.com/en-us/library/aa691087(v=vs.71).aspx
【解决方案2】:

你不能在调试器中看到它们,但你可以将它们输出到文件中,然后用比记事本更好的编辑器来查看它们,比如记事本++

File.WriteAllText("tmp.txt", invalidUserInput, UTF8Encoding.GetEncoding("UTF-8"));

【讨论】:

    【解决方案3】:

    在这种情况下,因为您可能会多次使用数据,您可能只想记录两个字符数组之间唯一的字符。为此,您可以使用Union 方法,如下所示:

    private static string invalidUserInput = new string(Path.GetInvalidFileNameChars().Union(Path.GetInvalidPathChars()).ToArray()); 
    

    【讨论】:

      【解决方案4】:

      运行您的代码会返回许多 unicode 字符:

      "|□□□□□□□□□ □□ □□□□□□□□□□□□□□□□□□:*?\/"|□□□□□□□□□ □□ □□□□□□□□□□□□□□□□□□

      你确定你没有因为 unicode 字符而丢失任何东西吗?

      另外,那是您的准确代码吗?如果您切换变量初始化的顺序,它将不再起作用,因为 invalidUserInput 必须在其他两个之后进行评估(它们按照它们在代码中定义的顺序进行评估)。

      【讨论】:

        猜你喜欢
        • 2022-01-04
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多