相对于隐式/显式转换"为"关键词相对于、关键词、隐式、QUOT

2023-09-03 00:39:02 作者:王者归来

我试图做一个项目,遗憾的是有单位的相互依存程度高一些的单元测试。目前,我们的很多类的看向自定义的的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.

这是一个pretty的直接的方法:

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;
    }

问题是,据我所知道的,那是因为似乎并没有援引任何对我的模仿对象的隐性或显性的转换操作。我的问题(s)是(是谁?),我失去了一些简单的在这里还是将无法工作,因为(我猜)的'作为'的操作看起来直接到类的继承(这我的对象没有做...) ?

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和示例显示了运营商要在生成的类,而不是源类,但我不知道如果该事项或没有(我试过在code以下两个地方) 。无论哪种方式,我试图建立一个简单的测试平台,看看有什么我可能是做错了,但我不能得到那个工作要么...这是我已经得到了

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.

当然,我失去了一些东西明显。是否指的IIdentity,我有我的身份(中富)的事实以某种方式使用$执行类型的明确经营者投的对$ pvent分辨率?这将感到奇怪。

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;
}

和(具有清理引起的具有两类运营商的不明确的引用后),它没有踏进我的显式转换操作符code和它的工作预期。所以我想它看起来像明确的运营商都不会多态解析(就是正确的认识?),而事实上,我的财产类型为IIdentity的,而不是一个ExtendedIdentity $ P $甚至从调用投逻辑尽管pvented它在它被调用时的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对象的门将,使其认识到我的特殊测试投嘲笑。我想封装的特殊的逻辑转换为模拟本身,所以这确实引发了我一个循环。

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.

推荐答案

由于不会调用转换操作符。请参阅: http://msdn.microsoft.com/ EN-US /库/ cscsdfbt(V = VS.100)的.aspx

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

使用一个(投)。