Activator.CreateInstance with private sealed class

后端 未结 4 2254
野性不改
野性不改 2020-12-17 17:30

I\'m trying to new up a LocalCommand instance which is a private class of System.Data.SqlClient.SqlCommandSet. I seem to be able to grab the type information just fine:

相关标签:
4条回答
  • 2020-12-17 17:39

    I got it to work this way:

    using System;
    using System.Reflection;
    
    class Test
    {
        public String X { get; set; }
    
        Test(String x)
        {
            this.X = x;
        }
    }
    
    class Program
    {
        static void Main()
        {
            Type type = typeof(Test);
    
            ConstructorInfo c = type.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
                null, new Type[] { typeof(String) }, null);
    
            Object o = c.Invoke(new Object[] { "foo" });
        }
    }
    

    The trick was to go after the constructor specifically with GetConstructor rather then trying to find it in the results of GetConstructors. Go figure.

    0 讨论(0)
  • 2020-12-17 17:44

    My first thought would be to get the ConstructorInfo using ConstructorInfo constructorInfo = Type.GetConstructor(), and then constructorInfo.Invoke() that. I suspect that Activator.CreateInstance makes it hard to call constructors you wouldn't normally have access to, although I don't remember trying it myself.

    0 讨论(0)
  • 2020-12-17 17:51

    Trick is to make sure to use the right CreateInstance overload:

    // WRONG
    ... Activator.CreateInstance(
           type,
           BindingFlags.Instance
           | BindingFlags.NonPublic
        );
    

    This calls the params overload, which will default to Instance | Public | CreateInstance, and your binding flags will be passed as arguments to the constructor, giving the vague MissingMethodException.

    Also, use Instance | Public | NonPublic if you aren't sure of the visibility of the constructor:

    // right
    ... Activator.CreateInstance(
           type,
           BindingFlags.Instance
           | BindingFlags.Public
           | BindingFlags.NonPublic,
           null,
           new object[] { }, // or your actual constructor arguments
           null
        );
    
    0 讨论(0)
  • 2020-12-17 17:58

    I might be a little late in responding, but I ran into a similar problem that fits into this topic.
    I wanted to instantiate a non public constructor using Activator.CreateInstance and passing it arguments.

    public class Node
    {
        string name;
        Node parent;
    
        protected Node(string name,Node parent)
        {
           this.name = name;
           this.parent = parent;
        }
    
        public static Node Create(string name,Node parent)
        {
           Node result = Activator.CreateInstance(
             type: typeof(Node),
             bindingAttr: BindingFlags.Instance  | BindingFlags.NonPublic,
             binder: null, //default binder
             args: new object[] { name, parent },
             culture: null);
           return (Node)result;
        }
    }
    

    The tricky part was the binding flags.

    My first instinct was to use BindingFlags.CreateInstance | BindingFlags.NonPublic, however that caused an exception to be thrown: MissingMethodException Constructor on type 'Node' not found.

    0 讨论(0)
提交回复
热议问题