If we must be inconsistent, we should endeavor to be consistent about it

by Michael S. Kaplan, published on 2007/02/21 04:31 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2007/02/21/1733999.aspx

The GEO stuff in the .NET Framework is not very consistent.

I mean, there is a RegionInfo.GeoId property that will return the same GEOID value as a call to GetLocaleInfo with an LCTYPE value of LOCALE_IGEOID (0x0000005B for those who don''t have the latest copy of winnls.h) for a given locale.

But what about RegionInfo.CurrentRegion and it's GeoId property?

After all, the GEOID value is the whole "Location" that is overrideable in Regional and Language Options.

And any time you look at data that can be overridden in the CultureInfo class when accessed via CultureInfo.CurrentCulture, you get the override. so why doesn't CurrentRegion give the same consideration?

Well, for starters there is no RegionInfo constructor that includes a parameter to control whether you allow overrides. And CultureInfo with overrides for the culture that happens to be the same as CurrentCulture. So if CurrentRegion allowed overrides to affect its value and CurrentRegion had the same behavior, then it would be impossible to get the GeoId for the current region if it is changed in Regional Options.

If an extra constructor were added, it would probably be too late to affect what CurrentRegion does since it would require changing the current behavior.

So RegionInfo and CultureInfo are not entirely consistent in the way they handle data that can be overridden.

Though on the other hand, GetLocaleInfo is not very consistent with the way it handles LOCALE_IGEOID as opposed to all the other overrideable fields, either.

Which I guess means that RegionInfo.CurrentRegion and it's RegionInfo.GeoId property are consistent with their unmanaged cousin. So at least they are consistently inconsistent.

And on top of that, those user settings are per-thread in .NET; is there any real need for a per-thread GEOID? The other user data being per thread is weird enough, trust me.

You can always pinvoke to GetUserGeoID to get the current user's GEOID, after all:

using System;
using System.Runtime.InteropServices;

public class Test {

    private enum GEOCLASS : int {
        NATION  = 16,
        REGION  = 14,

    [DllImport("kernel32.dll", ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
    private static extern int GetUserGeoID(GEOCLASS GeoClass);

    public static void Main() {

Maybe the next version of the .NET Framework needs a GeoInfo class and that class needs a static CurrentGeo property? :-)


This post brought to you by  (U+223a, a.k.a. GEOMETRIC PROPORTION)

# Miral on 21 Feb 2007 7:27 PM:

The culture stuff being per-thread is intended mainly for server applications, so that they can ask their clients what their culture is and then set the culture of the thread to match, so that they end up talking in the same language.  Since a server will be processing multiple connections, each of which could be in different cultures, the culture settings are per-thread since usually a single thread does all the processing for a given connection.

I haven't looked at the RegionInfo stuff at all, but if there's an option that lets you set the current region (without affecting the Control Panel) then it'll be per-thread for exactly the same reason.

Please consider a donation to keep this archive running, maintained and free of advertising.
Donate €20 or more to receive an offline copy of the whole archive including all images.

go to newer or older post, or back to index or month or day