Общего типа приведения недостаточно для правильного получения «нового» свойства - PullRequest
2 голосов
/ 29 ноября 2011

Мне нужно решить одну проблему в универсальном типе.

Для юнит-теста у меня есть один поддельный тип ScriptManager, подобный этому:

public class FakeScriptManager : ScriptManager
{
   public new virtual bool IsNavigating { get; private set; }
}

Мой проверенный метод выглядит следующим образом:

    public string GetHistoryPoint<TScriptManager>(string key, TScriptManager scriptManager)
            where TScriptManager : ScriptManager
{
          TScriptManager realScriptManager = Convert.ChangeType(scriptManager, scriptManager.GetType());
          if (realScriptManager.IsNavigating)
          {
              // Do something
          }
}

Метод тестирования выглядит следующим образом:

using (FakeScriptManager scriptManager = new FakeScriptManager(true, false))
{
    object value = _handler.GetHistoryPoint(keyExists, scriptManager);
}

Я намереваюсь установить свойство NEW IsNavigating is true для переменной FakeScriptManager.Но это невозможно.Переменная realScriptManager, по-видимому, не может быть преобразована из ожидаемого универсального типа TScriptManager.

Примечание: Отладка, попытка привести непосредственно входной параметр scriptManager с конкретным типом FakeScriptManager, это нормально.

Итак, моя проблема: Как сделать так, чтобы метод GetHistoryPoint общего типа работал должным образом, как я ожидал? Кто-нибудь, пожалуйста, помогите мне?

1 Ответ

1 голос
/ 29 ноября 2011

Почти во всех случаях сокрытие метода (new) - неправильная вещь; лучший подход был бы override в почти в каждом случае . Мой основной ответ здесь будет: удалить new.

Компилятор делает правильные вещи; он знает только о IsNavigating через TScriptManager : ScriptManager, поэтому неудивительно, что он его использует. Обобщения C # не похожи на шаблоны C ++; они могут использовать полиморфизм и т. д. из известной (where) структуры типа, и не не ищет наилучшего соответствия для фактического T только на основе имени (типизированный ввод) 1014 *

Если вам действительно нужно это, то либо отражение, либо, в 4.0, dynamic (что полностью утка набрано):

dynamic obj = scriptManager;
if((bool)obj.IsNavigating) {
       ...
}

(обратите внимание, что вышеописанное может не работать для "явной реализации интерфейса", но это не то, что вы делаете)

Convert.ChangeType здесь ничего полезного не делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...