Как передать className в метод, который получает универсальный тип в качестве параметра в C # - PullRequest
2 голосов
/ 22 декабря 2011

У меня есть много классов, отражающих мой экранный репозиторий от White / UIAutomation. Чтобы использовать репозиторий, мне нужно создать множество классов, отражающих экраны окон моего приложения.

Для создания хранилища я использую следующий метод:

var repoReport = repository.Get<MyClassRepresentingWindow>("WindowTitle", 
InitializeOption.WithCache);

он передает общий тип, подготовленный для класса I.

Я хочу создать словарь (stringClassName, string windowTitle) или любую карту для передачи этому методу. Проблема не может передать className как в Java ClassForName.

Я пытался System.Activator, но безуспешно.

Object configObj = System.Activator.CreateInstance(c);
Type c = System.Type.GetType("Namespace.MyClassRepresentingWIndow");

var myClass = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance("Namespace.MyClassRepresentingWIndow");

Type type = assembly.GetType("Namespace.MyClassRepresentingWIndow");
object obj = Activator.CreateInstance(type);

var repoReport = repository.Get<c>("WindowTitle", 
InitializeOption.WithCache);

var repoReport = repository.Get<c.Name>("WindowTitle", 
InitializeOption.WithCache);

Update1 Ребята, я не сижу перед кодом, но постараюсь сделать мой вопрос менее сложным.

Это метод, который я нашел в репозитории White, который, я думаю, я использую: https://github.com/petmongrels/white/blob/itemsmap/Components/Repository/Source/ScreenRepository.cs

public virtual T Get<T>(string title, InitializeOption option) where T : AppScreen
    {
        ClearClosedScreens();
        AppScreen screen;
        var repositoryCacheKey = new ScreenRepositoryCacheKey(title, typeof (T));
        if (!screenCache.TryGetValue(repositoryCacheKey, out screen))
        {
            Window window = applicationSession.Application.GetWindow(title, IdentifiedOption<T>(option));
            screen = GetScreen<T>(window);
            screenCache.Add(repositoryCacheKey, screen);
        }

        if (screen != null)
            sessionReport.Next(typeof (T));
        return (T) screen;
    }

Насколько я помню, VS отображал .Get as .Get <тип "class">. Извините, я не могу выразить себя лучше. Пожалуйста, возьмите с собой пациента, потому что я не знаком с этой терминологией.

Update2

В конце я хочу получить что-то вроде этого:

var repoReport1 = repository.Get<MyClassRepresentingWindow1>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow2>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow3>("WindowTitle", InitializeOption.WithCache);

И у меня есть код MyClassRepresentingWindow{1,2,3}. Я просто не знаю, как передать имя класса в метод Get. На входе у меня есть строковое имя этого класса. На выходе я хочу предоставить что-то, что может получить этот метод .Get<T>. Надеюсь, теперь вы меня понимаете.

Ответы [ 2 ]

3 голосов
/ 23 декабря 2011

Чтобы вызвать это с аргументом типа переменной, значение которого известно только во время выполнения, вам нужно использовать отражение.Я предполагаю, что вы знаете, как получить MethodInfo, представляющий метод репозитория Get<T>.

Получив это, этот пример иллюстрирует основную идею использования объекта MethodInfo.В примере предполагается, что класс repository называется Repo;измените это при необходимости:

object InvokeGenericMethod(Repo repository, MethodInfo method, Type typeArg, string arg1, InitializeOption arg2)
{
    MethodInfo constructedMethod = method.MakeGenericMethod(typeArg);
    return constructedMethod.Invoke(repository, new object[] { arg1, arg2 });
}

Конечно, вы можете сделать это более общим, но это сделало бы пример менее понятным.

1 голос
/ 22 декабря 2011

Я верю, что вы хотите что-то вроде этого:

    public string GetName<T>()
    {
        return typeof(T).Name;
    }

Это приводит к прохождению следующего модульного теста («Базовая математика» - это просто тип, который я использовал в своем приложении для работы с нулями):

    [TestMethod]
    public void Test_Of_Generic_Type_Name()
    {
        var myBuilder = new GenericNamer();

        Assert.AreEqual<string>("BasicMath", myBuilder.GetName<BasicMath>());
    }

Вы также можете использовать полное имя типа, сборку и т. Д. Вот еще немного информации о том, что вы можете извлечь из класса Type с помощью отражения:

http://msdn.microsoft.com/en-us/library/system.type.aspx

...