我试图在运行时设置方法的类型。当用户从下拉列表中选择类型时会发生这种情况。有许多不同的类型都从同一个接口继承。
这是我解释问题的代码......
接口
public interface IFoo
{
string Id { get; set; }
string Title { get; set; }
}
实施IFoo
的类:
Foo1
,Foo2
,Foo3
,Foo4
,...
类名称放入List<string>
以在我的MVC视图的下拉列表中显示:
private static IEnumerable<string> GetAllFooItems()
{
var a = typeof(IFoo).Assembly;
var itemTypes = from type in a.GetTypes()
where type.GetInterfaces().Contains(typeof(IFoo))
select Activator.CreateInstance(type) as IFoo;
return itemTypes.Select(instance => instance.GetType().Name).ToList();
}
将List
作为下拉列表的IEnumerable<SelectListItem>
的方法:
private static IEnumerable<SelectListItem> GetSelectListItems(IEnumerable<string> elements)
{
return elements.Select(element => new SelectListItem
{
Value = element,
Text = element
}).ToList();
}
用户从IFoo
项目的下拉列表中选择我要使用我的模型在以下获取方法上设置IFoo
的类型:
public T Get<T>(string id) where T : IFoo
{
// do something
}
这是我的模型:
public class FooModel
{
[DisplayName("Item Id: ")]
public string Id { get; set; }
[DisplayName("Content Type: ")]
public IFoo FooItem { get; set; }
public IEnumerable<SelectListItem> FooItems { get; set; }
}
我的控制器:
public class FooController : Controller
{
FooClient client = new FooClient("Foo"); // Placement of my Get Method (above)
[HttpGet]
public ActionResult FooSearch()
{
var fooTypes = GetAllFooItems();
var model = new FooModel();
model.FooItems = GetSelectListItems(fooTypes);
return View(model);
}
[HttpPost]
public ActionResult FooSearch(FooModel model)
{
var fooTypes = GetAllFooItems();
model.FooItems = GetSelectListItems(fooTypes);
client.Get<model.FooItem>(model.id); // model.FooItem does not work
// !!! I cannot set the Type from the model...
if (!ModelState.IsValid)
{
return View(model);
}
return View();
}
}
如果有人知道如何根据下拉选项更改方法中的Type参数,我将非常乐意找到答案。如果您需要更多信息,请告诉我们。
答案 0 :(得分:1)
您可以使用Reflection来调用Get
方法,如下所示:
var result = (IFoo) client.GetType()
//get the generic Get<T> method
.GetMethod("Get", new Type[] {typeof (string)})
//get the specific Get<model.FooItem> method
.MakeGenericMethod(model.FooItem.GetType())
.Invoke(client, new object[] { model.id }); //Invoke the method
顺便说一下,在获取可能类型名称的代码中,您不必创建每种类型的实例来获取名称。相反,您可以执行以下操作:
return (from type in a.GetTypes()
where type.GetInterfaces().Contains(typeof(IFoo))
select type.Name).ToList();