Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetOriginalTypeParameterType throws Object reference not set to an instance of an object exception

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.

  • outer: Object reference not set to an instance of an object.
  • inner: Microsoft.CSharp.RuntimeBinder.SymbolTable.GetOriginalTypeParameterType(Type t) +10

    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.

  • like image 528
    Travis J Avatar asked Aug 23 '12 17:08

    Travis J


    People also ask

    How do I fix object reference is not set to an instance of an object?

    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.

    What is object reference in C#?

    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.

    What is object reference in asp net?

    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.


    1 Answers

    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 :)

    like image 191
    Stuart Avatar answered Nov 15 '22 07:11

    Stuart