我在使用Visual Studio 2010比较C#4.0中的单元测试中的字符串时遇到问题.同样的测试用例在Visual Studio 2008中正常工作(使用C#3.5).
这是相关的代码段:
byte[] rawData = GetData();
string data = Encoding.UTF8.GetString(rawData);
Assert.AreEqual("Constant", data, false, CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)
在调试此测试时,该data
字符串在肉眼看来包含与文字完全相同的字符串.当我打电话data.ToCharArray()
时,我注意到该字符串的第一个字节data
是价值65279
这是UTF-8字节顺序标记.我不明白的是为什么要Encoding.UTF8.GetString()
保持这个字节.
如何获取Encoding.UTF8.GetString()
到不把字节顺序标记得到的字符串中?
更新:问题在于GetData()
,它从磁盘读取文件,使用从文件中读取数据FileStream.readbytes()
.我通过使用a StreamReader
并使用字符串将字符串转换为字节来纠正这个问题Encoding.UTF8.GetBytes()
,这应该是它本来应该做的事情!谢谢你的帮助.
对于字符串比较,哪种方法更好(和安全):
string s1="Sarfaraz";
string s2="Nawaz";
bool result1 = (s1==s2) ;//approach 1
bool result2 = s1.Equals(s2) ;//approach 2
Run Code Online (Sandbox Code Playgroud)
或两者在引擎盖下相同?
在编写单元测试时,我常常遇到这样的情况equals()
,即测试中的某个对象assertEquals
应该与在实际环境中的工作方式不同.以某些界面为例ReportConfig
.它有id
几个其他领域.逻辑上,当一个配置id
匹配时,一个配置等于另一个配置.但是,当谈到测试某些特定实现时XmlReportConfig
,显然我希望匹配所有字段.一种解决方案不是equals
在测试中使用,只是迭代对象属性或字段并进行比较,但它似乎不是一个好的解决方案.
因此,除了这种特定类型的情况之外,我想要理清什么是在语义上而不是在技术上实现平等的最佳实践.
public class Address{
public string ContactName {get; private set;}
public string Company {get; private set;}
//...
public string Zip {get; private set;}
}
Run Code Online (Sandbox Code Playgroud)
我想实现一个distint地址的概念,所以我重写了Equals()来测试所有字段中不区分大小写的相等性(因为这些是US地址,我使用Ordinal而不是InvariantCulture来获得最大性能):
public override bool Equals(Object obj){
if (obj == null || this.GetType() != obj.GetType())
return false;
Address o = (Address)obj;
return
(string.Compare(this.ContactName, o.ContactName, StringComparison.OrdinalIgnoreCase) == 0) &&
(string.Compare(this.Company, o.Company, StringComparison.OrdinalIgnoreCase) == 0)
// ...
(string.Compare(this.Zip, o.Zip, StringComparison.OrdinalIgnoreCase) == 0)
}
Run Code Online (Sandbox Code Playgroud)
我想像这样写一个GetHashCode()(暂时忽略连接效率低下):
public override int GetHashCode(){
return (this.contactName + this.address1 + this.zip).ToLowerOrdinal().GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
但那不存在.我应该用什么呢?或者我应该在我的Equals()方法中使用InvariantCulture?
(我在想.ToLowerInvariant().GetHashCode() …
我知道,为了比较两个浮点值,需要使用一些epsilon精度,因为它们并不精确.但是,我想知道是否有边缘情况,我不需要那个epsilon.
特别是,我想知道做这样的事情总是安全的:
double foo(double x){
if (x < 0.0) return 0.0;
else return somethingelse(x); // somethingelse(x) != 0.0
}
int main(){
int x = -3.0;
if (foo(x) == 0.0) {
std::cout << "^- is this comparison ok?" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道有更好的方法可以编写foo
(例如,另外返回一个标志),但我想知道一般情况下是否可以分配0.0
给浮点变量然后将其与之比较0.0
.
或者更一般,以下比较是否总是如此?
double x = 3.3;
double y = 3.3;
if (x == y) { std::cout << "is an epsilon required here?" << std::endl; }
Run Code Online (Sandbox Code Playgroud)
当我尝试它时,似乎工作,但可能是一个人不应该依赖它.
我理解==和.equals之间的区别.这里还有很多其他问题可以解释细节上的差异,例如这一点:.Equals和==这一点之间的区别是什么:其他许多人之间的比例平等.
我的问题是:为什么他们两个(我意识到必须有一个很好的理由) - 他们似乎都做同样的事情(除非被覆盖不同).
什么时候==会以不同的方式超载.equals被覆盖?
我正在为一位同事写一个有启发性的例子,告诉他为什么测试花车的平等往往是个坏主意.我去的例子是添加0.1十次,对1.0(我在我的介绍数值类所示)进行比较.我惊讶地发现两个结果是相同的(代码+输出).
float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
@float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Run Code Online (Sandbox Code Playgroud)
一些调查表明,这个结果不能依赖(很像浮动平等).我发现最令人惊讶的是在其他代码之后添加代码可能会改变计算结果(代码+输出).请注意,此示例具有完全相同的代码和IL,并附加了一行C#.
float @float = 0.0f;
for(int @int = 0; @int < 10; @int += 1)
{
@float += 0.1f;
}
Console.WriteLine(@float == 1.0f);
Console.WriteLine(@float.ToString("G9"));
Run Code Online (Sandbox Code Playgroud)
我知道我不应该在花车上使用平等,因此不应该太在意这一点,但我发现它非常令人惊讶,就像我向大家证明的那样.做的东西后,您进行了计算改变了先前计算的价值?我不认为这是人们通常在脑海中计算的模型.
我不是完全难住了,似乎是安全的假设,有某种优化的改变计算的结果,"平等"的情况下发生的(建筑在调试模式防止"平等"的情况下).显然,当CLR发现稍后需要将浮动框打包时,优化被放弃.
我搜索了一下但找不到这种行为的原因.任何人都能提醒我吗?
我有以下代码:
object val1 = 1;
object val2 = 1;
bool result1 = (val1 == val2);//Equals false
bool result2 = val1.Equals(val2); //Equals true
Run Code Online (Sandbox Code Playgroud)
那是怎么回事?修复此问题的唯一方法是使用.Equals()方法吗?
假设我有以下clojure函数:
(defn a [x] (* x x))
(def b (fn [x] (* x x)))
(def c (eval (read-string "(defn d [x] (* x x))")))
Run Code Online (Sandbox Code Playgroud)
有没有办法测试函数表达式的相等性 - 有些相当于
(eqls a b)
Run Code Online (Sandbox Code Playgroud)
返回true?
根据Python文档:"在定义时__eq__()
,还应该定义__ne__()
操作符将按预期运行".
然而,似乎Python的计算__ne__
为not __eq__
自动:
In [8]: class Test:
def __eq__(self, other):
print("calling __eq__")
...: return isinstance(other, Test)
...:
In [9]: a = Test()
In [10]: b = Test()
In [11]: a == b
calling __eq__
Out[11]: True
In [12]: a != b
calling __eq__
Out[12]: False
In [13]: a == 1
calling __eq__
Out[13]: False
In [14]: a != 1
calling __eq__
Out[14]: True
Run Code Online (Sandbox Code Playgroud)
那么定义__ne__
它是否恰好是return not self.__eq__(other)
什么意义呢?而且,这种行为实际记录在哪里? …