关于“as"的隐式/显式转换关键词 [英] Implicit/Explicit conversion with respect to the "as" keyword

查看:18
本文介绍了关于“as"的隐式/显式转换关键词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对一个不幸具有高度单元相互依赖性的项目进行一些单元测试.目前,我们的很多类都使用自定义的 UserIdentity 对象来确定身份验证,但是该对象有很多内部跳圈问题,我在尝试测试单个单元功能时会尽快避免这些问题.

I'm trying to do some unit testing on a project that unfortunately has high level of unit interdependence. Currently, a lot of our classes look to a custom UserIdentity object to determine authentication, but that object has a lot of internal hoop-jumping that I would just as soon avoid when trying to test individual unit functionality.

为了解决其中的一些问题,我正在尝试创建此 UserIdentity 的模拟"版本,该版本可以插入到更严格控制的变量环境中.

To work around some of this, I'm trying to create a "mock" version of this UserIdentity that can be plugged in with a more tightly-controlled variable environment.

长话短说,我们有一个 UserIdentity 类,其中包含几个公共只读属性和一个静态 CurrentIdentity (IIdentity) 占位符.我可以通过模拟"IIdentity 实现解决几乎所有问题,但是当我到达将 CurrentIdentity 强制转换为 UserIdentity 的点时,我遇到了墙强>.

Long story short, we have a UserIdentity class with several public read-only properties and a static CurrentIdentity (IIdentity) placeholder. I'm able work around just about everything with a "mock" IIdentity implementation, but I'm running into a wall when I reach a point where the CurrentIdentity is cast as a UserIdentity.

这是一种非常直接的方法:

It's a pretty straight-forward method:

internal static UserIdentity GetCurrentIdentity()
{
    UserIdentity currentIdentity = ApplicationContext.User.Identity as UserIdentity;
    return currentIdentity;
}

我已经设置了我的模拟对象来创建 UserIdentity 类型的成员,然后执行如下操作:

I've set up my mock object to create a member of the UserIdentity type, and then do something like this:

    public static implicit operator UserIdentity(MockUserIdentity src)
    {
        return src.UserIdentity;
    }

或者这个

    public static explicit operator UserIdentity(MockUserIdentity src)
    {
        return src.UserIdentity;
    }

问题是,据我所知,as"似乎不会对我的模拟对象调用隐式或显式转换操作.我的问题是(是?),我是否在这里遗漏了一些简单的东西,或者这将不起作用,因为(我猜)'as' 操作直接查看类继承(我的对象不这样做......)?

The problem is that as far as I can tell, that 'as' doesn't seem to invoke either an implicit or explicit conversion operation on my mock object. My question(s) is(are?), am I missing something simple here or will this not work because (I'm guessing) the 'as' operation looks directly to class inheritance (which my object does not do...)?

另外,也许有点离题,但为什么在一个类中不能同时存在相同结果类型的显式和隐式运算符?除非我遗漏了一些愚蠢的东西,否则编译器会阻止我尝试同时使用两个转换运算符.我必须选择一个.

Also, a bit off topic maybe, but why can there not be simultaneous explicit and implicit operators of the same resultant type within a class? Unless I'm missing something silly, the compiler balks if I try to have both conversion operators at once. I have to pick one or the other.

更新

好吧,现在我彻底糊涂了.也许我变得草率了,但我尝试过直接演员,但我似乎也无法让它发挥作用.我在 MSDN 上阅读了运算符,该示例显示运算符进入结果类而不是源类,但我不确定这是否重要(我在下面的代码中尝试了两个地方).无论哪种方式,我都试图建立一个简单的测试平台,看看我可能做错了什么,但我也无法让它工作......这就是我所拥有的

Okay, now I'm thoroughly confused. Maybe I'm getting sloppy, but I've tried doing the direct cast, and I can't seem to get that to work either. I read up on the operator at MSDN, and the example shows the operator going in the resultant class rather than the source class, but I'm not sure if that matters or not (I tried both places in the code below). Either way, I tried to set up a simple test bed to see what I might be doing wrong, but I can't get that to work either...Here's what I've got

class Program
{
    // Shared Interface
    public interface IIdentity { }

    // "real" class (not conducive to inheritence)
    public class CoreIdentity : IIdentity
    {
        internal CoreIdentity() { }

        // Just in case (if this has to be here, that seems unfortunate)
        public static explicit operator CoreIdentity(ExtendedIdentity src)
        {
            return src.Identity;
        }
    }

    // "mock" class (Wraps core object)
    public class ExtendedIdentity : IIdentity
    {
        public CoreIdentity Identity { get; set; }
        public ExtendedIdentity()
        {
            Identity = new CoreIdentity();
        }

        // This is where the operator seems like it should belong...
        public static explicit operator CoreIdentity(ExtendedIdentity src)
        {
            return src.Identity;
        }
    }

    // Dummy class to obtain "current core identity"
    public class Foo
    {
        public IIdentity Identity { get; set; }
        public CoreIdentity GetCoreIdentity()
        {
            return (CoreIdentity)Identity;
        }
    }

    static void Main(string[] args)
    {
        ExtendedIdentity identity = new ExtendedIdentity();
        Foo foo = new Foo();
        foo.Identity = identity;
        CoreIdentity core = foo.GetCoreIdentity();
    }
}

但是当我调用 foo.GetCoreIdentity() 时会抛出以下异常:

But that throws the following exception when I invoke foo.GetCoreIdentity():

无法将ExtendedIdentity"类型的对象转换为CoreIdentity"类型.

而且我无法通过断点捕获我的任何一个显式运算符,因此看起来它甚至没有尝试"我提供的转换路线就做出了这个决定.

and I can't catch either of my explicit operators with a break point, so it looks like it's making this determination without even "trying" the conversion routes I've provided.

我当然遗漏了一些明显的东西.我将我的身份(在 Foo 中)定义为 IIdentity 的事实是否会以某种方式阻止使用实现类型的显式运算符解析转换?那会让我觉得很奇怪.

Surely I'm missing something obvious. Does the fact that I have my Identity (in Foo) defined as IIdentity somehow prevent resolution of the cast using the explicit operators of the implementing type? That would strike me as odd.

更新(#2)

我觉得我正在用所有这些更新来垃圾邮件我的帖子(也许我应该在如此触发快乐之前采取行动:))无论如何,我修改了我的 Foo 的 GetCoreIdentityMethod 来执行此操作:

I feel like I'm spamming my post with all these updates (maybe I should get my act together before being so trigger-happy :) ) Anyway, I modified my Foo's GetCoreIdentityMethod to do this instead:

public CoreIdentity GetCoreIdentity()
{
    ExtendedIdentity exId = Identity as ExtendedIdentity;
    if (exId != null)
        return (CoreIdentity)exId;

    return (CoreIdentity)Identity;
}

并且(在必须清除由于在两个类中都包含运算符而导致的模糊引用之后),它确实进入了我的显式转换运算符代码,并且确实按预期工作.所以我想看起来显式运算符没有以多态方式解析(这是正确的理解吗?),并且我的属性被输入为 IIdentity 而不是 ExtendedIdentity 的事实阻止了它调用强制转换逻辑,即使它属于调用时的 ExtendedIdentity 类型.这让我觉得非常奇怪和出乎意料……而且有点不幸.

and (after having to clean up the ambiguous reference caused by having the operator in both classes), it did step into my explicit conversion operator code, and it did work as expected. So I guess it looks like the explicit operators are not resolved polymorphically (is that the correct understanding?), and the fact that my property was typed as an IIdentity rather than an ExtendedIdentity prevented it from invoking the cast logic even though it was of the ExtendedIdentity type at the time it was invoked. That strikes me as very peculiar and unexpected....and kind of unfortunate.

我不想重新编写 CurrentIdentity 对象的 keeper 以使其了解我的特殊测试转换模拟.我想将那个特殊"逻辑封装到模拟本身中,所以这真的让我陷入了循环.

I don't want to have to re-write the keeper of the CurrentIdentity object to make it aware of my special test cast mocks. I wanted to encapsulate that "special" logic into the mock itself, so this really throws me for a loop.

推荐答案

as 不调用转换运算符.请参阅:http://msdn.microsoft.com/en-us/library/cscsdfbt(v=VS.100).aspx

as does not invoke conversion operators. See: http://msdn.microsoft.com/en-us/library/cscsdfbt(v=VS.100).aspx

使用(演员表).

这篇关于关于“as"的隐式/显式转换关键词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆