我的团队之一最近在矩阵中遇到了一个有趣的故障。如果有人能帮助解释这一点,那就太好了。解释起来可能很复杂,所以请耐心等待。
我们正在构建一个ASP.Net应用程序。在其中我们有一个简单的“if”语句。
Guid adminId = Guid.Empty;
if (mRoles.Contains("Admin"))
{
adminId = mUserId;
}
(其中mRoles是一个List并包含“Admin”)
这与预期的一样(即adminID被分配了mUserId)。但是,当重写使用下面的三元运算符时它不会! (adminID被分配Guid Empty)!
Guid adminId = mRoles.Contains("Admin") ? mUserId : Guid.Empty;
发现这个的开发人员是在64位计算机(IIS7 / 64位vista)上,如果他在IIS中更改其设置,如下所示... 在“默认应用程序池”下> “高级设置”选中“启用32位应用程序”。现在这两个陈述都有效!
我们认为这可能是因为Guid是一个结构而不是一个类,并且该值在某种程度上在64位进程下被抵消。
我怀疑问题与此类似...... http://www.mail-archive.com/comtypes-users@lists.sourceforge.net/msg00164.html 这可以解释为什么第一个简单的if语句有效。 (因为创建adminId变量可能是创建指针而三元运算符不是?)
如果有人能够阐明这一点,那就太好了。 这是兼容性错误吗?或者我们对三元运算符和结构组合的误解?
感谢。
更新
组合一个简单的应用程序,无法在一个全新的项目中重现它,所以必须是GUID之外的其他东西。
// Works(将mUserId指定给adminId)
Guid adminId = true ? mUserId : Guid.Empty;
//不工作(即使t == true !!!! ???)
bool t = (mRoles.Contains("TenantAdmin");
Guid adminId = t ? mUserId : Guid.Empty;
我想我们会回到这个问题的绘图板上。感谢大家的帮助,如果我们再进一步,我会再次回到这里。
唯一可能不太清楚的是mRoles不是Type字符串的通用列表。它是一个字符串[],并且Contains()方法是LINQs扩展方法,如果这有任何区别,但无法理解为什么: - ?
更新2
我们已经查看了IL并且它是正确的(现在间歇性地工作!)我们发现当默认应用程序池加载更多应用程序时它再次开始失败。我们唯一能想到的是,其中一些应用程序可能包含一些非托管代码,这些代码会以某种方式干扰我们的应用程序,这可能吗?
答案 0 :(得分:1)
如果您还没有这样做,请在您的三元运算符周围尝试括号。
我们遇到了类似的问题:像你这样的代码:
Guid adminId = t ? mUserId : Guid.Empty;
以错误的顺序编译:
(Guid adminId = t) ? mUserId : Guid.Empty;
添加括号以指定修正它的顺序:
Guid adminId = (t ? mUserId : Guid.Empty);
通过使用.NET Reflector查看已编译的代码,我弄明白它在做什么。
答案 1 :(得分:0)
也许有助于明确告诉赋值运算符三元运算符的返回值是Guid吗?
Guid adminId = (Guid)(mRoles.Contains("Admin") ? mUserId : Guid.Empty);
只是猜测......
答案 2 :(得分:0)
只是想知道64位机器认为mUserId是什么类型的?大概不是指导。
答案 3 :(得分:0)
我不确定,但是我认为在使用三元运算符时,必须执行两个分支,但是使用GUID时,这可能会导致两个GUID被评估。
答案 4 :(得分:0)
您是否尝试过以下操作:
Guid adminId = mRoles.Contains("Admin") ? (Guid)mUserId : Guid.Empty;
只是好奇,无论出于何种原因,mUserId在64位操作系统下被内部识别为不同类型,并且如果显式转换会有所帮助。以下也可能是一个选项:
Guid adminId = mRoles.Contains("Admin") ? new Guid(mUserId.ToByteArray()) : Guid.Empty;
答案 5 :(得分:0)
这似乎是IIS中的一个错误,另一个应用程序运行在同一个应用程序池中的一大块非托管代码。我们现在已经解决了这个问题,并将通过我们的合作关系与微软合作。当它得到解决后,我会回到这里告诉你。
感谢大家的帮助。