我的团队最近在编程中遇到了一个有趣的问题,可能需要一些复杂的解释,请耐心听我讲述。我们正在开发一个ASP.Net应用程序,在其中使用了一个简单的"if"语句。
Guid adminId = Guid.Empty;
if (mRoles.Contains("Admin"))
{
adminId = mUserId;
}
(其中mRoles是一个列表,包含“Admin”)
这个代码按预期工作(即将mUserId分配给adminID)。然而,当重写为在下面使用三元运算符时,它不起作用!(adminID被分配了空的Guid)!
Guid adminId = mRoles.Contains("Admin") ? mUserId : Guid.Empty;
这位开发者在64位机器(IIS7/64-bit vista)上发现了这个问题,如果他按照以下方式更改IIS设置...在"默认应用程序池(Default Application Pool)"下的"高级设置(Advanced Settings)"中勾选"启用32位应用程序"。现在两个语句都可以工作了!
我们认为这可能与Guid是一个结构体而不是类有关,值在64位进程下被偏移了。
我怀疑问题类似于这个... http://www.mail-archive.com/comtypes-users@lists.sourceforge.net/msg00164.html 这可能解释了为什么第一个简单的if语句可以工作。(因为创建adminId变量可能会创建一个指针,三元运算符不会?)
如果有人能解释一下这个问题就太好了。 这是兼容性错误吗?还是我们对三元运算符和结构体的组合理解有误?
谢谢。
更新
组合了一个简单的应用程序,在一个全新的项目中无法重现这个问题,所以必须是GUID之外的其他原因。
// 工作正常(将mUserId分配给adminId)
Guid adminId = true ? mUserId : Guid.Empty;
// 不起作用(即使t == true !!!!???)
bool t = (mRoles.Contains("TenantAdmin");
Guid adminId = t ? mUserId : Guid.Empty;
我认为我们需要重新开始思考这个问题。感谢大家的帮助,如果有进一步的消息,我会再次在这里发布。
唯一可能不太清楚的是mRoles不是一个类型为string的通用列表。它是一个string[],而Contains()方法是LINQ的扩展方法,如果有任何区别,但看不出来 :-?
更新2
我们已经查看了IL代码,并且是正确的(现在间歇性地工作!)。我们发现当默认应用程序池加载更多应用程序时,它开始再次失败。我们能想到的唯一其他事情是,一些其他应用程序可能包含一些非托管代码,这些代码某种方式干扰了我们的应用程序,这可能是可能的吗?