参考:How can a dynamic be used as a generic?
public void CheckEntity(int entityId, string entityType = null)
{
dynamic AnyObject = Activator.CreateInstance("Assembly","Assembly.Models.DbModels." + entityType).Unwrap();
CheckWithInference(AnyObject, entityId);
}
private static void CheckWithInference<T>(T ignored, int entityId) where T : class
{
Check<T>(entityId);
}
private static void Check<T>(int entityId) where T : class
{
using (var gr = new GenericRepository<T>())
{
}
}
这与CheckEntity(16,"Container");
一起输入。第一行运行后,AnyObject
在使用调试程序检查时变为空白Assembly.Models.DbModels.Container
。如果使用var AnyType = AnyObject.GetType();
,则AnyType
显示为Assembly.Models.DbModels.Container
。但是,当调用CheckWithInference(AnyObject, entityId);
时,会抛出异常。
我在这里制作了一个自包含的示例 - 但它运行没有错误:(
注意,这是在asp.net mvc 3 c#
中HomeController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace InferenceExample.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
public void CheckEntity(int entityId, string entityType = null)
{
dynamic AnyObject = Activator.CreateInstance("InferenceExample", "InferenceExample.Models." + entityType).Unwrap();
CheckWithInference(AnyObject, entityId);
}
private static void CheckWithInference<T>(T ignored, int entityId) where T : class
{
Check<T>(entityId);
}
private static void Check<T>(int entityId) where T : class
{
var repo = new List<T>();
}
}
}
Example.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace InferenceExample.Models
{
public class Example
{
public int ExampleId { get; set; }
public string Name { get; set; }
}
}
Index.cshtml
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@Html.ActionLink("Start", "CheckEntity", new { entityId = 16, entityType = "Example" })
我不知所措。为什么会得到这个例外?我无法轻易复制它。我不确定该示例还包含哪些内容,因为这是实际代码中的所有内容。
真正令人困惑的部分是在应用程序中,当发生此异常时,操作失败。但是,在重新访问页面并再次尝试时,不会抛出任何异常。
答案 0 :(得分:3)
正如在C#聊天室中所讨论的,这里的解决方案是完全绕过动态并使用反射来调用泛型方法。 Dynamic有一些不错的功能,但有时会造成比它值得更多的麻烦,特别是当它可以在运行时获取Type对象时。
var modelType = Type.GetType("InferenceExample.Models." + entityType + ",InferenceExample");
var checkMethod = typeof(HomeController).GetMethod("CheckWithInference", BindingFlags.NonPublic | BindingFlags.Static);
checkMethod.MakeGenericMethod(modelType).Invoke(null, new object[] { entityId });
很高兴帮助:)