Неявное / явное преобразование по отношению к ключевому слову «как»

Я пытаюсь провести какое-то модульное тестирование в проекте, который, к сожалению, имеет высокий уровень взаимозависимости модулей. В настоящее время многие наши классы обращаются кUserIdentity объект для определения аутентификации, но этот объект имеет много внутренних скачков, которые я бы так же быстро избегал при попытке проверить функциональность отдельных модулей.

Чтобы обойти это, я пытаюсь создать «фиктивную» версию этого UserIdentity, которую можно подключить к более жестко контролируемой переменной среде.

Короче говоря, у нас есть класс UserIdentity с несколькими общедоступными свойствами только для чтения и статическим CurrentIdentity (IIdentity) заполнитель. Я могу обойти почти все с "насмешкой"IIdentity реализации, но я наталкиваюсь на стену, когда достигаю точки, где CurrentIdentity приводится какUserIdentity.

Это довольно простой метод:

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

Я создал свой фиктивный объект, чтобы создать членаUserIdentity введите, а затем сделайте что-то вроде этого:

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

или это

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

Проблема в том, что, насколько я могу судить, это «как» не вызывает ни явной, ни явной операции преобразования моего фиктивного объекта. Мой (ые) вопрос (и): я пропускаю что-то простое здесь или это не сработает, потому что (я предполагаю) операция 'as' смотрит прямо на наследование классов (что мой объект не делает ...) ?

Кроме того, может быть, немного не по теме, но почему в классе не может быть одновременных явных и неявных операторов одного и того же результирующего типа? Если я не пропустил что-то глупое, компилятор не работает, если я пытаюсь использовать оба оператора преобразования одновременно. Я должен выбрать один или другой.

ОБНОВИТЬ

Хорошо, теперь я полностью сбит с толку. Может быть, я становлюсь неаккуратным, но я попытался сделать прямое приведение, и я не могу заставить это работать. Я прочитал об операторе в MSDN, и в примере показан оператор, идущий в результирующий класс, а не в исходный класс, но я не уверен, имеет ли это значение или нет (я пробовал оба места в коде ниже). В любом случае, я пытался установить простой тестовый стенд, чтобы увидеть, что я могу делать неправильно, но я тоже не могу заставить это работать ... Вот что у меня есть

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 ():

Невозможно привести объект типа «ExtendedIdentity» к типу «CoreIdentity».

и я не могу поймать ни один из моих явных операторов с точкой останова, так что похоже, что он делает это определение, даже не «пробуя» маршруты конвертации, которые я указал.

Конечно, я упускаю что-то очевидное. Помогает ли тот факт, что мой Identity (в Foo), определенный как IIdentity, как-то мешает разрешению приведения с использованием явных операторов реализующего типа? Это показалось бы мне странным.

ОБНОВЛЕНИЕ (# 2)

У меня такое чувство, что я спамую в своем сообщении со всеми этими обновлениями (возможно, я должен собрать свои действия, прежде чем быть настолько счастливым для триггера :)) В любом случае, я изменил метод GetCoreIdentityMethod моего Foo, чтобы сделать это вместо этого:

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

    return (CoreIdentity)Identity;
}

и (после очистки неоднозначной ссылки, вызванной наличием оператора в обоих классах), он вошел в мой явный код оператора преобразования и работал должным образом. Поэтому я думаю, что это выглядит так, как будто явные операторы не разрешаются полиморфно (это правильное понимание?), И тот факт, что мое свойство было напечатано как IIdentity, а не как ExtendedIdentity, препятствовало тому, чтобы оно вызывало логику приведения, даже если это было Тип ExtendedIdentity во время его вызова. Это кажется мне очень странным и неожиданным ... и довольно неудачным.

Я не хочу переписывать хранитель объекта CurrentIdentity, чтобы он знал о моих специальных тестовых приведениях. Я хотел включить эту «особую» логику в сам макет, так что это действительно заставляет меня задуматься.

Ответы на вопрос(4)

Ваш ответ на вопрос