如何在 C# 中将 className 传递给将泛型类型作为参数的方法
我有很多类反映了 White/UIAutomation 的屏幕存储库。 要使用存储库,我需要创建许多反映应用程序窗口屏幕的类。
为了创建存储库,我使用以下方法:
var repoReport = repository.Get<MyClassRepresentingWindow>("WindowTitle",
InitializeOption.WithCache);
它传递一个泛型类型,该类型是我准备的类。
我想要做的是创建一个 Dictionary(stringClassName, string windowTitle) 或任何映射来传递给该方法。 问题是无法像 Java ClassForName 那样传递 className。
我尝试了 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);
更新1 伙计们,我不会坐在代码前面,但我会尽力使我的问题不那么复杂。
这是我在 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 作为 .Get<"class" type>。很抱歉我无法更好地表达自己。请有一位病人和我一起,因为我不熟悉这个术语。
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
可以获得的东西。 我希望你现在能理解我。
I have lots of classes reflecting my screen Repository from White/UIAutomation.
To use repository I need to create lots of classes that reflect screens of my application windows.
To create a repository I use the following method:
var repoReport = repository.Get<MyClassRepresentingWindow>("WindowTitle",
InitializeOption.WithCache);
it passes a generic type which is a Class I prepared.
What I want to do is to create a Dictionary(stringClassName, string windowTitle) or any Map to pass to that method.
The problem is can't pass className like in Java ClassForName.
I tried System.Activator
but without any success.
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
Guys, I'm not sitting in front of the code but I'll try to make my question less complicate.
This is a method which I found in the White repository that I think I use:
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;
}
As I remember VS displayed .Get as a .Get<"class" type>. I'm sorry I can't express myself better. Please have a patient with me because I'm not familiar with this terminology.
Update2
At the end I want to get something like this:
var repoReport1 = repository.Get<MyClassRepresentingWindow1>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow2>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow3>("WindowTitle", InitializeOption.WithCache);
And I have a code of MyClassRepresentingWindow{1,2,3}
. I just don't know how to pass class name to Get method. On input I have a string name of this class. On output I want to deliver something that this method .Get<T>
can get.
I hope you can understand me now.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了使用变量类型参数调用它,其值仅在运行时才知道,您需要使用反射。我假设您知道如何获取表示存储库的
Get
方法的MethodInfo
。一旦您了解了这一点,此示例将说明如何使用 MethodInfo 对象的基本思想。该示例假设
repository
类名为Repo
;根据需要进行更改:当然,您可以使其更加通用,但这会使示例变得不太清晰。
In order to call this with a variable type argument, whose value is only known at run time, you need to use reflection. I assume that you know how to get the
MethodInfo
representing the repository'sGet<T>
method.Once you have that, this example illustrates the basic idea how to use the MethodInfo object. The example assumes that the
repository
class is calledRepo
; change that as needed:You could make this more generic, of course, but that would have made the example less clear.
我相信您想要的是这样的:
这会导致以下单元测试通过(“基本数学”只是我在草稿应用程序中放置的一种类型):
您还可以使用该类型的全名、程序集等以下是有关使用反射从 Type 类中提取内容的更多信息:
http://msdn.microsoft.com/en-us/library/system.type.aspx
I believe what you want is something like this:
That causes the following unit test to pass (the "Basic Math" is just a type I had laying around in my scratch application):
You could also use the type's full name, assembly, etc. Here's some more information on what you can pull out of the Type class using reflection:
http://msdn.microsoft.com/en-us/library/system.type.aspx