Linux上的Mono .NET - 字符串比较失败

时间:2014-03-11 17:14:23

标签: .net mono

我第一次潜入Mono并且变得更奇怪(也就是不可能)的行为。

我正在Windows上的Visual Studio 2012中进行编译,然后将二进制文件复制到运行CentOS 6.5的虚拟机,并使用最新的稳定版Mono运行时。

当我在Mono运行时中运行二进制文件时,字符串比较方法无法按预期运行。它第一次工作正常,但后来在执行阶段它的行为有所不同,即使字符串相同,String.Equals(...)也返回FALSE。

public static class DBUtils
    {

        public static string ProviderConnectionStringFromEFConnectionString(string efConnectionStringName)
        {
            Console.WriteLine();
            Console.WriteLine("DBUTILS:");
            Console.WriteLine("We are looking for '{0}'", efConnectionStringName);
            string efConnString = getConnectionString(efConnectionStringName);

            if (string.IsNullOrWhiteSpace(efConnString))
            {
                Console.WriteLine("ERROR - EFConnString is blank or null");
                return "";
            }
            else
                Console.WriteLine("Got EF connection string which is '{0}'", efConnString);

            // <snip>
        }

        static string getConnectionString(string connStringName)
        {
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            var csSection = config.ConnectionStrings;

            Console.WriteLine("Searching {0} connection strings for {1}...", csSection.ConnectionStrings.Count, connStringName);

            for (int i = 0; i < csSection.ConnectionStrings.Count; i++)
            {
                var conn = csSection.ConnectionStrings[i];

                Console.WriteLine(" compare {0}<=>{1}", conn.Name, connStringName);

                if ( conn.Name == connStringName)
                {
                    Console.WriteLine("FOUND " + conn.Name);
                    return conn.ConnectionString;
                }
            }

            Console.WriteLine("NOT FOUND");
            return null;
        }
    }

...控制台输出如下。上述方法两次运行两次,结果不同:

DBUTILS:
We are looking for 'transit_UK_intranet'
Searching 4 connection strings for transit_UK_intranet...
 compare LocalSqlServer<=>transit_UK_intranet
 compare LocalSqliteServer<=>transit_UK_intranet
 compare transit_UK_intranet<=>transit_UK_intranet
FOUND transit_UK_intranet
Got EF connection string which is 'metadata=res://*/Transit.TransitModel.csdl|res://*/Transit.TransitModel.ssdl|res://*/Transit.TransitModel.msl;provider=MySql.Data.MySqlClient;provider connection string="server=transportdata.fatattitude.intranet;user id=root;password=mys***y;persist security info=True;database=transit_uk"'

然后,后来:

DBUTILS:
'e are looking for 'transit_UK_intranet
...rching 4 connection strings for transit_UK_intranet
 compare LocalSqlServer<=>transit_UK_intranet
 compare LocalSqliteServer<=>transit_UK_intranet
 compare transit_UK_intranet<=>transit_UK_intranet
 compare transit_UK_live<=>transit_UK_intranet
NOT FOUND
ERROR - EFConnString is blank or null

传递给该方法的字符串是另一个类中保存的Public Static字符串,该字符串作为另一个类中构造函数的一部分引用,然后调用此静态帮助程序方法。

有没有人有任何想法?我注意到上面第二个输出中的奇怪的控制台损坏。 ('e are......rching)。

**

更新2:

**

根据Jon Skeet的要求,这里是控制台输出,只有长度/哈希码比较。

DBUTILS:
We are looking for 'transit_UK_intranet'

connStringName as unicode chars:0074,0072,0061,006E,0073,0069,0074,005F,0055,004B,005F,0069,006E,0074,0072,0061,006E,0065,0074

Searching 4 connection strings for transit_UK_intranet...
 Compare (Length:14,Hash:-1122305114)<=>(Length:19,Hash:1351687580)
 Compare (Length:17,Hash:1337257306)<=>(Length:19,Hash:1351687580)
 Compare (Length:19,Hash:1351687580)<=>(Length:19,Hash:1351687580)
FOUND transit_UK_intranet

第二种方法调用:

DBUTILS:
'e are looking for 'transit_UK_intranet

 connStringName as unicode chars:0074,0072,0061,006E,0073,0069,0074,005F,0055,004B,005F,0069,006E,0074,0072,0061,006E,0065,0074,000D

...rching 4 connection strings for transit_UK_intranet
 Compare (Length:14,Hash:-1122305114)<=>(Length:20,Hash:-1047357967)
 Compare (Length:17,Hash:1337257306)<=>(Length:20,Hash:-1047357967)
 Compare (Length:19,Hash:1351687580)<=>(Length:20,Hash:-1047357967)
 Compare (Length:15,Hash:-529357175)<=>(Length:20,Hash:-1047357967)

致电代码:

 Console.WriteLine(" Compare (Length:{0},Hash:{1})<=>(Length:{2},Hash:{3})", 
 conn.Name.Length, conn.Name.GetHashCode(),
 connStringName.Length, connStringName.GetHashCode() );

1 个答案:

答案 0 :(得分:0)

0x000D char是\ r \ n,因此看起来某些代码可能无法正确处理行结束。如果没有看到所有代码,如果这是单声道代码或您自己的代码或某些支持库代码,很难说。

具体来说,在Linux和其他unix系统上,线路终端由单个字符符号\ n发出信号,而在Windows上则表示\ r \ n。所以使用windows文本行的代码,但是unix终止符可能只删除一行末尾的\ n,所以你留下了\ r \ n字符,你无法在控制台中看到但是它会混淆输出并且字符串的比较不同。