76

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 party library and the constructor is internal. The reasons I want to do this are complicated but it would be helpful to know if it's possible using some kind of C# hackery.

NOTE: I specifically do not want to call any constructor so using reflection to access the internal constructor is not an option.

Wai Ha Lee
8,856101 gold badges61 silver badges97 bronze badges
asked Nov 17, 2008 at 19:24
3
  • 3
    Related note to this and some people tend not to realize is that if you throw an exception during construction, your object still exists.. if it has a finalizer- that will still run, you need to be careful about making no assumptions about what happened in the constructor. Commented Apr 19, 2009 at 10:13
  • Why would you ever want this? If it is just curiosity, that's fine. Commented Jan 2, 2014 at 13:07
  • @nawfal WCF uses this for its serialization engine, which is one reason it is useful in general. My specific case was actually playing around with an existing object model (the SharePoint OM) to see if it were possible to work around some bugs/limitations for experimental purposes. Very hacky for sure, but again, experimental. Commented Jan 9, 2014 at 1:36

12 Answers 12

100

I have not tried this, but there is a method called FormatterServices.GetUninitializedObject that is used during deserialization.

Remarks from MSDN says:

Because the new instance of the object is initialized to zero and no constructors are run, the object might not represent a state that is regarded as valid by that object.

Simon
35k22 gold badges142 silver badges210 bronze badges
answered Nov 17, 2008 at 20:33
7
  • In my case, it's only for prototyping. Not for real code that anyone would use for anything remotely important. Commented Nov 18, 2008 at 6:34
  • I'm planning on using it for deserializing a DataContract object from an unsuported serialized format. Commented Nov 27, 2011 at 0:01
  • 7
    I have tested this out and can confirm that FormatterServices.GetUninitializedObject() does not avoid static ctor's from being called. :( Commented Aug 9, 2012 at 9:24
  • 4
    @JasonEvans I don't think you can ever stop static ctors from being run, as the CLR loads them when the type is loaded. You can't actually refer to a class at all without loading it's type, so I'm not sure quite how you'd get around it Commented Jan 8, 2014 at 19:29
  • 1
    @nawfal Reflection isn't practical in all cases. The whole reason I asked this question is because I was dealing with a type which had an internal constructor requiring parameters which themselves were complex internal types. Using reflection turned out to be too difficult to generate these other related types without falling down a slippery slope of endless reflection. Commented Jan 9, 2014 at 1:31
10

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.

Scott Dorman
42.6k12 gold badges82 silver badges112 bronze badges
answered Nov 17, 2008 at 19:27
7

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.

answered Dec 5, 2008 at 14:40
2

See RuntimeHelpers.GetUninitializedObject(Type), available in .NET Core 2.0 / .NET Standard 2.1 and above.

Another answer suggests FormatterServices.GetUninitializedObject(Type), which directly proxies to RuntimeHelpers.

For completeness, if you want to create an uninitialized object of the same type as another instance, in .NET Core 7 there is also an undocumented AllocateUninitializedClone, with sample code below. I wouldn't recommend this over simply passing instance.GetType() to the documented API.

Likewise, here are notes for if you actually want to hit an internal constructor:

Given a Type and some arguments.

Use Activator.CreateInstance(Type type, object[] args).

Alternatively via Reflection APIs

Use type.GetConstructor. The returned ConstructorInfo has an Invoke method. If you pass an instance, you will effectively reinitialize an object. If you pass no instance, the invocation will instantiate a new object.

Some sample code:

using System.Reflection;
using System.Runtime.CompilerServices;
public static class Program {
 public static void Main() {
 //
 // create uninitialized object instance, then run ctor on it
 //
 var inst1 = (C)RuntimeHelpers.GetUninitializedObject(typeof(C));
 Console.WriteLine(inst1.X); // 0
 var ctor = typeof(C).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>());
 ctor.Invoke(inst1, null); // Prints "Ran C's Ctor. X is -123"
 Console.WriteLine(inst1.X); // 2
 //
 // create new object with ctor (via reflection)
 //
 var inst2 = (C)ctor.Invoke(null); // Prints "Ran C's Ctor. X is -123"
 Console.WriteLine(inst2.X); // 2
 //
 // create new object with ctor (via activator)
 //
 var inst3 = (C)Activator.CreateInstance(typeof(C), BindingFlags.Instance | BindingFlags.NonPublic, null, null, null); // Prints "Ran C's Ctor. X is -123"
 Console.WriteLine(inst3.X); // 2
 //
 // create new uninitialized object of type matching a given instance via undocumented AllocateUninitializedClone
 //
 var allocateUninitializedClone = typeof(RuntimeHelpers).GetMethod("AllocateUninitializedClone", BindingFlags.Static | BindingFlags.NonPublic, new[] { typeof(object) });
 var inst4 = (C)allocateUninitializedClone.Invoke(null, new []{inst2});
 Console.WriteLine(inst4.X); // 0
 }
 public class C {
 private C() {
 Console.WriteLine($"Ran C's Ctor. X is {X}");
 X = 2;
 }
 public int X { get; } = -123;
 }
}
answered Dec 1, 2022 at 11:16
0

It might be possible to access the constructor via reflection and invoke it like that (but I'm not sure that it will work since the constructor is internal - you'll have to test it). Otherwise from my knowledge you can't create an object without calling the constructor.

answered Nov 17, 2008 at 19:26
0
0

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.

answered Nov 17, 2008 at 19:34
4
  • Haven't you just called the constructor without creating an object instance? (eg: the exact opposite of what the question is asking?) Commented Nov 17, 2008 at 19:52
  • I created the object by calling the hidden constructor, which is what he wanted until he edited his post. Commented Nov 17, 2008 at 19:55
  • The question's revision history disagrees with you. Perhaps this is dirty ol atwood trying to optimize things too much. I remember on a podcast he mentioned simply throwing away any record of changes that happened within a few minutes of the question being posted Commented Nov 17, 2008 at 20:53
  • stackoverflow.com/revisions/296584/list <-- I see him adding his note of clarification. Commented Nov 17, 2008 at 22:25
0

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.

answered Nov 17, 2008 at 20:22
0

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

answered Dec 9, 2014 at 21:40
-1

See the System.Activator.CreateInstance function.

answered Nov 17, 2008 at 19:29
2
  • Sadly, this is a proper answer. The question was edited after this post. Commented Jan 2, 2014 at 13:04
  • No, Activator.CreateInstance does invoke the constructor, as stated in the documentation. Commented Feb 9, 2023 at 14:14
-1

What you are asking to do is a violation of the philosophy upon which managed programming was developed. The .Net Framework and C# are built with the principle that, whenever possible, objects should be abstracted away from their underlying memory. Objects are objects, not a structured array of bytes. This is why you can't cast objects to void pointers willy-nilly. When objects are abstracted away from their underlying memory, it is fundamentally invalid to suggest that an object instance can exist without the constructor being invoked.

That said,the .Net framework has made concessions to the fact that in reality, objects are actually represented in memory. With some creativity, it is possible to instantiate value types without invoking their initializers. However, if you feel you need to do it, you're probably doing things wrong.

answered Nov 17, 2008 at 20:04
-1

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.

answered Apr 19, 2009 at 10:06
2
  • 2
    That's wrong. A parameter-less constructor will still be called. If there only are constructors with parameters, this cannot and will not compile. MSDN is missleading: it's not "without calling" just because you don't type it. Commented Apr 19, 2009 at 10:42
  • The linked MSDN article is very clear about this: "The compiler processes object initializers by first accessing the default instance constructor, and then by processing the member initializations. Therefore, if the default constructor is declared as private in the class, object initializers that require public access will fail." Commented Sep 13, 2011 at 7:33
-3

No one here has quite clarified what is meant by "It can't be done."

The constructor is what creates the object. Your question is akin to "How can I build a sand castle without shaping it like a castle?" You can't -- All you will have is a pile of sand.

The closest thing you could possible do is to allocate a block of memory the same size as your object:

byte[] fakeObject = new byte[sizeof(myStruct)];

(NOTE: even that will only work in MyStruct is a value type)

answered Nov 17, 2008 at 20:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.