Reference: 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>())
{
}
}
This enters with CheckEntity(16,"Container");
. After the first line runs, AnyObject
becomes a blank Assembly.Models.DbModels.Container
when inspected with the debugger. If var AnyType = AnyObject.GetType();
is used, then AnyType
shows as Assembly.Models.DbModels.Container
. However, when the call to CheckWithInference(AnyObject, entityId);
is made an exception is thrown.
I made a self-contained example here - but it runs without error :(
Note, this is in 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" })
I am at a loss. Why am getting this exception? I was unable to easily reproduce it. I am not sure what else to include for the example as this is all that the actual code has in it.
The really confusing part is that in the application, when this exception occurs, the action fails. However, upon revisiting the page and trying a second time, there is no exception thrown.
To fix "Object reference not set to an instance of an object," you should try running Microsoft Visual Studio as an administrator. You can also try resetting the user data associated with your account or updating Microsoft Visual Studio to the latest version.
In C#, classes and interfaces are reference types. Variables of reference types store references to their data (objects) in memory, and they do not contain the data itself. An object of type Object , string , or dynamic is also a reference type.
An Object is an instance of a Class , it is stored some where in memory. A reference is what is used to describe the pointer to the memory location where the Object resides.
As discussed in C# chat room, the solution here is to bypass dynamic entirely and use reflection to invoke the generic method. Dynamic has some nice features but sometimes causes more trouble than it's worth, especially when it's possible to get the Type object at runtime.
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 });
Glad to help :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With