如何System.String妥善包裹的情况下,insensitivy? [英] How can System.String be properly wrapped for case-insensitivy?

查看:132
本文介绍了如何System.String妥善包裹的情况下,insensitivy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题的没有的有关管理Windows路径名;我以前只作为一个不区分大小写的具体例子。 (我如果我改变的例子,现在,一大堆的意见将是毫无意义的。)

This question is not about managing Windows pathnames; I used that only as a specific example of a case-insensitive string. (And I if I change the example now, a whole bunch of comments will be meaningless.)

这可以类似于<一href="http://stackoverflow.com/questions/32146065/possible-to-create-case-insensitive-string-class">Possible创建不区分大小写字符串类?,但没有很多讨论存在。另外,我真的不关心紧密的语言集成的字符串享有或 System.String 的性能优化

This may be similar to Possible to create case insensitive string class?, but there isn't a lot of discussion there. Also, I don't really care about the tight language integration that string enjoys or the performance optimizations of System.String.

比方说,我用了很多的Windows路径名这是(通常)不区分大小写(我不是真正关心的是像实际路径的许多细节\ VS / \\\\ 是一样的 \ 文件:// 网​​址, .. 等)。一个简单的包装可能是:

Let's say I use a lot of Windows pathnames which are (normally) case-insensitive (I'm not actually concerned with the many details of actual paths like \ vs. /, \\\\ being the same as \, file:// URLs, .., etc.). A simple wrapper might be:

sealed class WindowsPathname : IEquatable<WindowsPathname> /* TODO: more interfaces from System.String */
{
    public WindowsPathname(string path)
    {
        if (path == null) throw new ArgumentNullException(nameof(path));
        Value = path;
    }

    public string Value { get; }

    public override int GetHashCode()
    {
        return Value.ToUpperInvariant().GetHashCode();
    }

    public override string ToString()
    {
        return Value.ToString();
    }

    public override bool Equals(object obj)
    {
        var strObj = obj as string;
        if (strObj != null)
            return Equals(new WindowsPathname(strObj));

        var other = obj as WindowsPathname;
        if (other != null)
            return Equals(other);

        return false;
    }
    public bool Equals(WindowsPathname other)
    {
        // A LOT more needs to be done to make Windows pathanames equal.
        // This is just a specific example of the need for a case-insensitive string
        return Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase);
    }
}

是的,所有/大部分的接口的 System.String 的可能应该执行;但上面好像够讨论的目的。

Yes, all/most of the interfaces on System.String should probably be implemented; but the above seems like enough for discussion purposes.

我现在可以这样写:

var p1 = new WindowsPathname(@"c:\foo.txt");
var p2 = new WindowsPathname(@"C:\FOO.TXT");
bool areEqual = p1.Equals(p2); // true  

这让我谈 WindowsPathname 在我的code,而不是实施细节如 StringComparison.OrdinalIgnoreCase 。 (是的,这的的具体的类也可以扩展到处理 \ VS / 使 C:/foo.txt 的将等于的 C:\ foo.txt的的,但是这不是这个问题点)。此外,这个类(有更多的接口)将不区分大小写,当实例添加到收藏;那就没有必要指定一个的IEqualityComparer 。最后,像这样的一个特定的类也可以更容易地prevent非意识操作,如一个文件系统路径比较一个注册表项。

This allows me to "talk about" WindowsPathnames in my code rather than a implementation detail like StringComparison.OrdinalIgnoreCase. (Yes, this specific class could also be extended to handle \ vs / so that c:/foo.txt would be equal to C:\FOO.TXT; but that's not the point of this question.) Furthermore, this class (with additional interfaces) will be case-insensitive when instances are added to collections; it would not necessary to specify an IEqualityComparer. Finally, a specific class like this also makes it easier to prevent "non-sense" operations such as comparing a file system path to a registry key.

的问题是:这样的做法是成功的?是否有任何严重的和/或细微的瑕疵或其他陷阱?(同样,不必做,试图建立一个不区分大小写字符串类,而不是管理Windows路径名。)

The question is: will such approach be successful? Are there any serious and/or subtle flaws or other "gotchas"? (Again, having to do with trying to setup a case-insensitive string class, not managing Windows pathnames.)

推荐答案

我将创建一个不可改变的结构持有一个字符串,将字符串中的构造标准的情况下(如小写)。 然后,你也可以添加隐式运算符来简化创建和覆盖比较运营商。 我认为这是实现该问题的最简单的方法,再加上你得到的只是一个小的开销(转换只在构造函数)。

I would create an immutable struct that hold a string, converting the string in the constructor to a standard case (e.g. lowercase). Then you could also add the implicit operator to simplify the creation and override the compare operators. I think this is the simplest way to achieve the behaviour, plus you get only a small overhead (the conversion is only in the constructor).

这里的code:

public struct CaseInsensitiveString
{
    private readonly string _s;

    public CaseInsensitiveString(string s)
    {
        _s = s.ToLowerInvariant();
    }

    public static implicit operator CaseInsensitiveString(string d)
    {
        return new CaseInsensitiveString(d);
    }

    public override bool Equals(object obj)
    {
        return obj is CaseInsensitiveString && this == (CaseInsensitiveString)obj;
    }

    public override int GetHashCode()
    {
        return _s.GetHashCode();
    }

    public static bool operator ==(CaseInsensitiveString x, CaseInsensitiveString y)
    {
        return x._s == y._s;
    }

    public static bool operator !=(CaseInsensitiveString x, CaseInsensitiveString y)
    {
        return !(x == y);
    }
}

下面是用法:

CaseInsensitiveString a = "STRING";
CaseInsensitiveString b = "string";

// a == b --> true

这适用于收藏为好。

这篇关于如何System.String妥善包裹的情况下,insensitivy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆