Create object instance without invoking constructor?

后端 未结 11 1864
不知归路
不知归路 2020-11-28 05:01

In C#, is there a way to instantiate an instance of a class without invoking its constructor?

Assume the class is public and is defined in a 3rd par

相关标签:
11条回答
  • 2020-11-28 05:17

    Contrary to what many believe, a constructor hasn't much to do with the instantiation of an object at all (pretty misleading term). A constructor is a special method that can be called after the instantiation of an object to allow that object to properly initialize itself. In C++ object instantiation allocates memory for the object, in .NET and Java it is both allocated and pre-initialized to default values depending on the type of fields (0, null, false etc.). Then the run-time calls the constructor. The new operator encapsulates these two separate actions into what appears to be a single operation. Deserialization could never had worked in .NET if it wasn't possible to create an instance without using a constructor. That said, the so called ConstructorInfo type acts as both a new operator and constructor when calling its Invoke(...) method.

    0 讨论(0)
  • 2020-11-28 05:17

    EDIT: You updated your question, you want to construct a class without a constructor. Or call a default "Empty Constructor".

    This cannot be done, as the compiler will not generate a default constructor if there is already one specified. However, for the benefit of the readers, here is how to get at a internal, protected, or private constructor:

    Assuming your class is called Foo:

    using System.Reflection;
    
    // If the constructor takes arguments, otherwise pass these as null
    Type[] pTypes = new Type[1];
    pTypes[0] = typeof(object);    
    object[] argList = new object[1];
    argList[0] = constructorArgs;
    
    ConstructorInfo c = typeof(Foo).GetConstructor
        (BindingFlags.NonPublic |
         BindingFlags.Instance,
         null,
         pTypes,
         null);
    
    Foo foo = 
        (Foo) c.Invoke(BindingFlags.NonPublic,
                       null, 
                       argList, 
                       Application.CurrentCulture);
    

    Ugly, but works.

    Of course, there may be a perfectly legitimate reason to mark a constructor as internal, so you should really consider the logistics of what you want before you abuse that class by getting at it with reflection.

    0 讨论(0)
  • 2020-11-28 05:20

    If the class (and the classes of objects that it references) is Serializable, you can create a deep copy by serializing using a BinaryFormatter that outputs to a MemoryStream (creating a byte array byte[]), then deserializing. See the answers to this question on converting an object to a byte array. (But note - saving the byte array to use later/elsewhere is likely not to work. IOW don't save the byte array to a file or other persistent form.)

    0 讨论(0)
  • 2020-11-28 05:26

    Actually it sounds like they made the constructor internal just so you can't instantiate it. It may have a builder or factory method.

    Check out these articles:

    Preventing Third Party Derivation: Part 1

    Preventing Third Party Derivation: Part 2

    they kind of explain the reasoning.

    0 讨论(0)
  • 2020-11-28 05:26

    I noticed the "deadness" of the subject but just for clarification on further readers and to put a final answer that maybe wasn't possible when the question was posted. Here it goes.

    It seems that you can instantiate a class without using it's constructors by assigning values to its properties. Here is the address where is the how-to in MSDN for this type of instantiation http://msdn.microsoft.com/en-us/library/bb397680.aspx.

    It seems like this is a technique that's not well known because I encountered it in a article in CodeProject and then googled it and didn't find anything about it and later on visited the MSDN Homepage and there was a post that linked me to that exact subject. So it seems that it's an unknown subject rather than a new one because the date on the CodeProject post dates May 2008.

    Hope this helps someone else that google's this and comes across with this question.

    0 讨论(0)
  • 2020-11-28 05:31

    You have to call a constructor to create an object. If there are none available to your liking perhaps you could use a byte code rewriting library like the Mono project's Cecil. It works on Windows as well as Linux. From some of the demos I saw, it looked pretty cool. You can change the protection levels of methods and all sorts of crazy stuff.

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