Globally set String.Compare/ CompareInfo.Compare t

2019-01-28 05:39发布

问题:

I'm searching for a strategy with which I can set the default sortorder of String.CompareTo to bytewise - ordinal. I need to do this without having to specify the sortorder in the call to the method.

I have tried out several strategies without satisfactory results. I got as far as this:

CultureAndRegionInfoBuilder crib = 
            new CultureAndRegionInfoBuilder("foo", CultureAndRegionModifiers.Neutral);

        CompareInfo compareInfo = new CustomCompareInfo();
        crib.Register();

In this CustomCompareInfo I try to override the default CompareInfo class, but unfortunately this does not compile:

The type 'System.Globalization.CompareInfo' has no constructors defined

I'm stuck here. Got the feeling that a custom implementation of CompareInfo is the solution to my problem.

Got any ideas on this?

Edit: context of my question:

This project I'm working on is quite unusual - a huge codebase has been converted from an other programming language to .NET. In this programming language the string comparison defaults to ordinal and this difference with .NET is causing bugs in the converted codebase, so I figured it would be the most elegant solution if we'd be able to configure .NET to the same default behavior.

Of course it is possible to reconvert the code using a comparison-specifier. Or, we could introduce an extension method which performs a ordinal (binary) comparison. Et cetera..

However, as far as I am concerned, from an architectural viewpoint, these solutions are less elegant. This is the reason why I am searching for a solution with which I can set this ordinal comparison globally on the framework.

Thanks in advance!

回答1:

Sorry, you can't make this work. The CompareInfo class does have a constructor. But it is internal and takes a CultureInfo as an argument. The actual implementation involves private members of CultureInfo that reflect sorting tables built into mscorlib. They are not extensible.

This does actually work in VB.NET, presumably the reason you are pursuing this. It has an Option Compare statement that lets you select binary comparison. This is however not implemented with CultureInfo, it is done by the compiler. Which recognizes a string comparison and replaces it with a custom vb.net string comparison method that is aware of the selected Option Compare. It's name is Microsoft.VisualBasic.CompilerServices.Operators.CompareString()

You cannot coax the C# compiler into the same behavior. You'd have to painstakingly replace comparison expressions in converted vb.net code. A horrible job of course and very prone to mistakes. If the conversion was done by a converter program then you might be better off with a good decompiler, it won't hide the CompareString() calls.



回答2:

There appears to be no means of setting the default comparison mode (here, to ordinal).

If what you want is always-consistent comparison results, you can set, for each thread you create in your app, the culture to 'invariant' (cultureInfo with empty string as parameter) Thread.CurrentThread.CurrentCulture = new CultureInfo(""); If you want to perform ordinal comparisons for performance, I really think that nothing can be done globally - you will need to pass this option explicitely each time you perform a string comparison.

Can you tell us what you need exactly?