隐式/显式转换关于“as”关键字的单元测试。目前,我们的许多类都在寻找自定义UserIdentity对象来确定身份验证,但是这个对象有很多内部跳跃,我在尝试测试单个单元的功能时会很快避免这些跳跃。为了解决其中一些问题,我正在尝试创建一个“模拟”版本的UserIdentity,它可以通过更严格控制的变量环境插入。简而言之,我们有一个UserIdentity类,其中包含几个公共只读属性和一个静态CurrentIdentity(IIdentity)占位符。我可以通过“模拟”IIdentity实现来解决所有问题,但是当我将CurrentIdentity转换为UserIdentity时遇到了障碍。这是一个非常简单的方法:internalstaticUserIdentityGetCurrentIdentity(){返回当前身份;我已经设置了我的模拟对象来创建一个UserIdentity类型的成员,然后执行以下操作:publicstaticimplicitoperatorUserIdentity(MockUserIdentitysrc){}或者这个publicstaticexplicitoperatorUserIdentity(MockUserIdentitysrc){returnsrc.UserIdentity;问题是“as”似乎不在我对模拟对象调用隐式或显式转换操作中。我的问题是(是吗?),我在这里遗漏了一些简单的东西,还是这不起作用,因为(我猜)'as'操作直接看到类继承(我的对象不这样做......)?另外,可能有点跑题了,但是为什么不能在一个类中同时使用相同结果类型的显式和隐式运算符呢?除非我遗漏了一些愚蠢的东西,否则如果我尝试同时使用两个转换运算符,编译器就会出现问题。我必须选择其中之一。更新好吧,现在我完全糊涂了。也许我变得马虎了,但我已经尝试过直接施法,但似乎无法让它发挥作用。我在MSDN上阅读了运算符,示例显示运算符进入结果类而不是源类,但我不确定这是否重要(我在下面的代码中尝试了两个地方)。无论哪种方式,我都在尝试建立一个简单的测试台,看看我可能做错了什么,但我也无法让它工作……这就是我所拥有的类程序{//SharedInterfacepublicinterfaceIIdentity{}//“真正的”类(不利于继承)publicclassCoreIdentity:IIdentity{internalCoreIdentity(){}//以防万一(如果必须在这里,那似乎很不幸)publicstaticexplicitoperatorCoreIdentity(ExtendedIdentitysrc){返回src.Identity;}}//“模拟”类(包装核心对象)publicclassExtendedIdentity:IIdentity{publicCoreIdentityIdentity{get;放;}publicExtendedIdentity(){Identity=newCoreIdentity();}//这就是运算符似乎应该属于的地方...publicstaticexplicitoperatorCoreIdentity(ExtendedIdentitysrc){returnsrc.Identity;}}//获取“当前核心身份”的虚拟类publicclassFoo{publicIIdentityIdentity{get;放;}publicCoreIdentityGetCoreIdentity(){return(CoreIdentity)Identity;}}staticvoidMain(字符串[]args){ExtendedIdentityidentity=newExtendedIdentity();富富=新富();foo.Identity=身份;CoreIdentity核心=foo.GetCoreIdentity();但是当我调用foo.GetCoreIdentity()时会抛出以下异常:无法将“ExtendedIdentity”类型的对象转换为“CoreIdentity”并且我无法捕获任何带有断点的显式运算符,所以看起来它没有做出这个决定甚至“尝试”我提供的转换路径。当然,我遗漏了一些明显的东西。我将我的身份(在Foo中)定义为IIdentity的事实是否会以某种方式阻止使用显式运算符来解析转换来实现类型?这让我想知道。更新(#2)我觉得我发送了所有这些更新的垃圾邮件(也许我应该齐心协力让触发快乐:))无论如何,我修改了我的Foo的GetCoreIdentityMethod改为:publicCoreIdentityGetCoreIdentity(){ExtendedIdentityexId=IdentityasExtendedIdentity;如果(exId!=null)返回(CoreIdentity)exId;返回(CoreIdentity)身份;}(在必须清除由两个类中的运算符引起的歧义引用之后),这确实进入了我的显式转换运算符代码,并且它按预期工作。所以我认为显式运算符看起来没有多态解析(理解正确吗?),而且我的属性被键入为IIdentity而不是ExtendedIdentity的事实阻止它调用转换逻辑,即使它是ExtendedIdentity类型通话时间。这让我感到非常特别和出乎意料……还有点不幸。我不想覆盖CurrentIdentity对象的管理器以使其知道我的特殊测试参与者模拟。我想将这个“特殊”逻辑封装到模拟本身中,所以这真的让我想到了一个循环。因为没有调用转换运算符。请参阅:http://msdn.microsoft.com/en-us/library/cscsdfbt(v=VS.100).aspxuse(cast)。我将我的身份(在Foo中)定义为IIdentity的事实是否会以某种方式阻止使用显式运算符来解析转换来实现类型?这里有个提示:如何定义显式(或隐式)转换运算符?(我知道你知道这个,因为你已经做到了;我问这个是为了说明一点。)publicstaticexplicitoperatorUserIdentity(MockUserIdentitysrc){用户身份;这里发生了一些非常重要的事情。C#设计者明智地选择将所有运算符设为静态。所以上面定义的显式运算符实际上转换为这样的静态方法调用:publicstaticUserIdentityop_Explicit(MockUserIdentitysrc){现在,这就是我要做的。在你的问题中困扰你的行为,因为它似乎在多态性部门失败了,实际上是C#的方法重载系统解决方案的结果。如果我有两种方法:voidWrite(strings){Console.WriteLine("string");}voidWrite(objecto){Console.WriteLine("object");}...然后我有这个程序:objectx="Hello!";写(x);输出结果是什么?答案是“对象”,因为编译器选择了Write(object)重载——它应该是。write不是按照正常的多态性被某些派生类型覆盖的实例方法;它是一个带有重载的静态方法,编译器必须在这些重载之间进行选择。由于上述代码中的x被声明为对象类型,因此明确选择Write(object)。所以对于你的代码,你有这个:publicIIdentityIdentity{get;放;}publicCoreIdentityGetCoreIdentity(){return(CoreIdentity)Identity;编译器必须调查:是否有接受op_Explicit参数的op_Explicit重载?不,不在那里。有一个采用UserIdentity参数,但它太具体了(因为上面示例中的Write(string)对于x来说太具体了)。因此,在初始测试中未调用显式运算符的原因是编译器未将(CoreIdentity)Identity解析为该特定重载。这就是您的修改版本起作用的原因:publicCoreIdentityGetCoreIdentity(){ExtendedIdentityexId=IdentityasExtendedIdentity;if(exId!=null){//因为exId实际上被声明为ExtendedIdentity类型,//编译器可以选择运算符重载来接受//ExtendedIdentity参数——所以这会起作用。返回(CoreIdentity)exId;}返回(CoreIdentity)身份;那么为什么不使用显式转换呢?//如果转换失败将抛出internalstaticUserIdentityGetCurrentIdentity(){UserIdentitycurrentIdentity=(UserIdentity)ApplicationContext.User.Identity;返回当前身份;这应该会触发您的显式运算符。您可以先进行测试以使其更安全。正如Ray提到的那样,不会调用转换运算符。也就是说,您应该在那种情况下使用显式转换。这样,当某些设置不正确并且ApplicationContext.User.Identity中的对象不是您的代码所期望的对象时,您会非常清楚。以上就是C#学习教程:as关键字隐式/显式转换分享的全部内容。如果对你有用,需要了解更多C#学习教程,希望大家多加关注——本文来自网络合集,不代表立场,如涉及侵权,请右击联系管理员删除。如需转载请注明出处:
