Is new-ing objects obsolete? - c#

Ok, so here's the question... is the new keyword obsolete?
Consider in C# (and java, I believe) there are strict rules for types. Classes are reference types and can only be created on the heap. POD types are created on the stack; if you want to allocate them on the heap you have to box them in an object type. In C#, structs are the exception, they can be created on the stack or heap.
Given these rules, does it make sense that we still have to use the new keyword? Wouldn't it make sense for the language to use the proper allocation strategy based on the type?
For example, we currently have to write:
SomeClassType x = new SomeClassType();
instead of
SomeClassType x = SomeClassType();
or even just
SomeClassType x;
The compiler would, based on that the type being created is a reference type, go ahead and allocate the memory for x on the heap.
This applies to other languages like ruby, php, et al. C/C++ allow the programmer more control over where objects are created, so it has good reason to require the new keyword.
Is new just a holdover from the 60's and our C based heritage?

SomeClassType x = SomeClassType();
in this case SomeClassType() might be a method located somewhere else, how would the compiler know whether to call this method or create a new class.
SomeClassType x;
This is not very useful, most people declare their variables like this and sometimes populate them later when they need to. So it wouldn't be useful to create an instance in memory each time you declare a variable.

Your third method will not work, since sometimes we want to define a object of one type and assign it to a variable of another type. For instance:
Stream strm = new NetworkStream();
I want a stream type (perhaps to pass on somewhere), but internally I want a NetworkStream type.
Also many times I create a new object while calling a method:
myobj.Foo(new NetworkStream());
doing that this way:
myobj.Foo(NetworkStream());
is very confusing. Am I creating an object, or calling a method when I say NetworkStream()?

If you could just write SomeClassType x; and have it automatically initialized, that wouldn't allow for constructors with any parameters. Not every SomeClassType will have a parameterless constructor; how would the compiler know what arguments to supply?
public class Repository
{
private IDbConnection connection;
public Repository(IDbConnection connection)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
this.connection = connection;
}
}
How would you instantiate this object with just Repository rep;? It requires a dependent object to function properly.
Not to mention, you might want to write code like so:
Dictionary<int, SomeClass> instances = GetInstancesFromSomewhere();
SomeClass instance;
if (instances.TryGetValue(1, out instance))
{
// Do something
}
Would you really want it auto-initializing for you?
If you just wrote SomeClassType x = SomeClassType() then this makes no distinction between a constructor and a method in scope.
More generally:
I think there's a fundamental misunderstanding of what the new keyword is for. The fact that value types are allocated on the stack and "reference" types are allocated on the heap is an implementation detail. The new keyword is part of the specification. As a programmer, you don't care whether or not it's allocated on the heap or stack (most of the time), but you do need to specify how the object gets initialized.
There are other valid types of initializers too, such as:
int[] values = { 1, 2, 3, 4 };
Voilà, an initialization with no new. In this case the compiler was smart enough to figure it out for you because you provided a literal expression that defines the entire object.
So I guess my "answer" is, don't worry about where the object exists memory-wise; use the new keyword as it's intended, as an object initializer for objects that require initialization.

For starters:
SomeClassType x;
is not initialized so no memory should be allocated.
Other than that, how do you avoid problems where there is a method with the same name as the class.
Say you write some code:
int World() { return 3; }
int hello = World();
and everything is nice and jolly.
Now you write a new Class later:
class World
{
...
}
Suddenly your int hello = World() line is ambiguous.

For performance reasons, this might be a bad idea. For instance, if you wanted to have x be a reference for an object that's already been created, it would be a waste of memory and processor time to create a new object then immediately dispose of it.

Wouldn't it make sense for the
language to use the proper allocation
strategy based on the type?
That's exactly what the C# compiler/runtime already does. The new keyword is just the syntax for constructing an object in whatever way makes sense for that object.
Removing the new keyword would make it less obvious that a constructor is being called. For a similar example, consider out parameters:
myDictionary.TryGetValue(key, out val);
The compiler already knows that val is an out. If you don't say so, it complains. But it makes the code more readable to have it stated.
At least, that is the justification - in modern IDEs these things could be found and highlighted in other ways besides actual inserted text.
Is new just a holdover from the 60's
and our C based heritage?
Definitely not. C doesn't have a new keyword.

I've been programming with Java for a number of years and I have never care if my object is on the heap or the stack. From that perspective is all the same to me to type new or don't type it.
I guess this would be more relevant for other languages.
The only thing I care is the class have the right operations and my objects are created properly.
BTW, I use ( or try ) to use the new keyword only in the factory merthod so my client looks like this anyway
SomeClasType x = SomeClasType.newInstance();
See: Effective Java Item:1

If you don't have a parameterless constructor, this could get ugly.
If you have multiple constructors, this could get real ugly.

Related

Why we write Employee emp = new Employee()

Just an academic question, why many programming languages have following like syntax for instantiation :
Employee emp = new Employee()
I mean, we don't use something like Employee emp = new Vehicle(). So, why not just say Employee emp or new Employee emp too instantiate.
Am I missing something too fundamental ?
In C# you can use var in order to let the compiler decide the data type of the variable.
For example:
var i = 5;
In addition, when handling inherited object, it is very common that the reference type and the instance type are not the same.
Well, every class in C# used by reference. Writing Employee emp = new Employee() assigns to value emp reference to object of the class Employee (pointer to somewhere in the sea of objects), and you can't use class by value, because of garbage collector and possible reallocation. Class objects are stored in the heap.
If you programmed in C++ (I believe you did), you know, that analogous code will
return pointer to object in the heap, not the object itself.
But C# have one custom type which can be passed by value, not by reference:
struct. And writing code
struct Employee{
...
}
...
Employee emp;
emp.cnt = 5
is perfectly valid, because struct initialized automatically, as do other value-types in C#.
It is just language design, nothing more.
Also CLR makes sure, that no object can be casted to type that is not defined in implicit/explicit cast constructions. That is what makes regular C# safe. But that may not be true in unsafe blocks. I used them only once and don't know much about them. Only that some operations that are not possible in safe blocks possible here.
First, it's not recommended
While this question might fall into "primarily opinion based" there is a best practice to use implicit typing along with the new keyword because the type is very obvious thanks to the type's constructor.
Use of var is known as implicit typing and it means you won't have to modify your code when, for example, a database provider must change.
Second, there's at least one time explicit typing makes sense
Numbers. Specifically decimal and the variety of integer sizes. Consider the following:
var num = 0;
With no other hinting, I'm allowing the compiler to decide the size, in memory, of that variable. Right now, that's Int32 and that's fine ... but what if that number has to go somewhere else? What if I'm writing that to a TCP socket and the client on the other end is expecting the serialized bytes of a ULong or UInt16
When working with numbers, and even more critically with money, explicit typing should be expected.
It is necessary to declare variable for storing information about the class(i.e. instance of that class)
To answer your question, we cannot use object/variable without declaring it, it is necessary to store your class instance in object/variable for maintaining information and using it further.
You can use scala where you can declare variable using val or var,
val is used when variable is used as constant ie. it won't change in future, otherwise use var
Intersting question 👍
First of all it depends on the programmimg language and where you want to declare the variable. If the variable is a member of your class then you have to declare a specific type. That is because, for some languages like C#, the compiler is creating a dll which has all the information about your class including class members. For that it need to be specific type.
We can concider C# as a safe programming language because it doesn't allow changing the type of a variable when first it is declared and assigned. However for some years ago C# inroduced the dynamic type and distroyed all that concepts 😂

C# - Object Creation

I'm a PHP programmer for some time. Two days ago, I went to a job interview where they gave me an assigment to do in ASP.NET ( C# ). I would really like to get out of the php sphere of influence and learn a decent language that can challenge me. So, I have a question
Do all instances have to be instantiated at runtime? In php, I can do something like this...
class SomeObject {}
$objString = "SomeObject";
$objInstance = new $objString();
I can't do that in C#, probably beacuse it's a compiled language. In C#, would I have to create a Factory pattern who will instantiate objects. That would also mean that if I have to instantiate 10 object in that Factory, that there would be 10 if statements which is ugly.
I found Activator object with its Activator::createInstance() method but I could't get it to work. Also there's Reflection, but both of these ( as I'm aware of ) are a performance impact.
So, is there a way to dynamicly create objects or could it be that in C#, i can immediatlly create all objects that my program will use, which is really tempting?
EDIT
Ok, so let's say that I have 5 object that are used in 5 different occassions. I run the program, the program evaluates that it needs one of those object and instantiates it. The other four are never instantiated. I close the program.
Second time, I run the program with different parameters, and 2 of those 5 objects are created, other three never came into existence.
This is easy in PHP. Let's put Activator and other tools aside, is it good practice in C# world to create all the 5 objects when I know that maybe, only one of them will be used?
I don't know if i got your question wrong, but creating object of your given class SomeObject in C# is as easy as the following:
var obj = new SomeObject();
Using the Activator-Class it should look sth. like one of the following
var obj2 = Activator.CreateInstance(typeof(SomeObject));
var obj3 = Activator.CreateInstance<SomeObject>();`
var someObjType = Type.GetType("SomeObject"); // if you have to use a string
var obj4 = Activator.CreateInstance(someObjType);
Note that using the Activator-Class for instanciating objects isn't necessary in most cases. The first example is the standard way if you know the Type of the Class at compiletime.
UPDATE
regarding your update, since i don't know the details what comes to my mind is lazy instanciation. Since everything, including the entry point of your application is an object in C#, you can solve the issue using properies with backed fields like in the following example
class Program
{
// backing fields
private SomeObject obj1;
private SomeObject obj2;
private SomeObject obj3;
private SomeObject obj4;
private SomeObject obj5;
// this way, obj1 only gets instanciated when needed
public SomeObject Obj1
{
get
{
if (obj1 == null)
{
obj1 = new SomeObject();
}
return obj1;
}
}
// same for the other objects
[...]
}
I you are concerned about the memory usage of your object, i recommend you to learn about how to properly implement IDisposable
UPDATE 2
To provide the possibility recommended in the comments by # Mad Sorcerer, you could back the fields using the Lazy-Class which takes some effort of your shoulder, the effect is quite the same as in the previous update.
class Program
{
// Lazy backing fields
private Lazy<SomeObject> obj1 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj2 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj3 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj4 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj5 = new Lazy<SomeObject>();
// this way, obj1 only gets instanciated when needed
public SomeObject Obj1
{
get { return obj1.Value; }
}
// same for the other objects
[...]
}
Yes, you can create objects dynamically in C#. But not as easily as in PHP.
As you found, there's Activator. It works fine when you use it correctly. :) There's also direct reflection (Activator is based on reflection as well). Both are slow when used naively.
Using the Expression type, it is possible to cache the logic for instantiating an object. It's still slow the first time, but if you expect to be creating the same type of object repeatedly, this approach works well (and if you don't, then the fact that it's slow via Activator doesn't matter :) ).
That said, most of the time you should not need to create objects dynamically like in your example. The strong, compile-time type-checking in C# should be taken advantage of, not eschewed. Writing code that instantiates objects for which the type is already known at compile time is most efficient, and most type-safe.
For those relatively few times where you do need dynamic behavior, it is possible.
So that PHP code... you're choosing which class to instantiate by it's name as a string?
You need to look up the type first and then instantiate it with Activator.
Type classType = Type.GetType("SomeObject");
object instance = Activator.CreateInstance(classType);
You can look up it's constructor and call that instead using reflection which looks more like this
Type classType = Type.GetType("SomeObject");
var ctorInfo = classType.GetConstructor(Type.EmptyTypes);
object instance = ctorInfo.Invoke(new object[] {});
and you can cache the constructor as a delegate which eliminates the performance penalty which comes from looking up stuff#
Note that Type.GetType has some issues of it's own. The above code will work if SomeObject is in the System namespace. You may need to add the namespace, class and sometime assembly. In all it's safest to use the AssemblyQualifiedName.
There are a few ways to create an instance of a class in C#.
The usual way is simply to use new:
MyType myInstance = new MyType();
For dynamically creating objects, based on their name for instance, Activator.Createinstance() works, but you must know the assembly where that class is defined so you can correctly create that instance.
However, especially if you are just beginning, I wouldn't bother with getting into this yet.
C# is a statically-typed language, meaning that resolution of type is made during compilation.
On top of that, consider that the IDE, Visual Studio, will help you tremendously since it can scan files in your project and know the Type of each of members you are typing in your code.
Statically-types languages are helpful in avoiding the exact sort of issues that arise in purely dynamic languages: they force you to be coherent, at the expense of requiring you to be explicit in your declaration (although C#, with the var keyword, can help a lot in avoiding that normally required verbosity).
So the whole point is to make sure that you declare all types your will need in your application.
If you need a particular class member to accept data from multiple other classes, you can use inheritance, creating a base class that others will inherit some behaviour from, or use Interfaces, to describe common members to a variety of types. Each has its advantages and drawbacks.
If you are dabbling with C#, just experimenting, I'd recommend getting LINQpad. It may help you experiment while learning.
I would also stay away from anything that's not canonical: understand idiomatic C# first before you go too deep in trying to do do runtime stuff.
One area you can explore though, is the dynamic type. It's not as flexible as what you'd expect from a truly dynamic language, but it's a way to deal with type-uncertainty.
It has a performance drawback though, and should be avoided if you want to benefit from Intellisense in Visual Studio and want to benefit from the normal type-checking that the IDE and compiler can provide for you.

Why anonymous methods inside structs can not access instance members of 'this'

I have a code like the following:
struct A
{
void SomeMethod()
{
var items = Enumerable.Range(0, 10).Where(i => i == _field);
}
int _field;
}
... and then i get the following compiler error:
Anonymous methods inside structs can not access instance members of 'this'.
Can anybody explains what's going on here.
Variables are captured by reference (even if they were actually value-types; boxing is done then).
However, this in a ValueType (struct) cannot be boxed, and hence you cannot capture it.
Eric Lippert has a nice article on the surprises of capturing ValueTypes. Let me find the link
The Truth About Value Types
Note in response to the comment by Chris Sinclair:
As a quick fix, you can store the struct in a local variable: A thisA = this; var items = Enumerable.Range(0, 10).Where(i => i == thisA._field); – Chris Sinclair 4 mins ago
Beware of the fact that this creates surprising situations: the identity of thisA is not the same as this. More explicitly, if you choose to keep the lambda around longer, it will have the boxed copy thisA captured by reference, and not the actual instance that SomeMethod was called on.
When you have an anonymous method it will be compiled into a new class, that class will have one method (the one you define). It will also have a reference to each variable that you used that was outside of the scope of the anonymous method. It's important to emphasize that it is a reference, not a copy, of that variable. "lambdas close over variables, not values" as the saying goes. This means that if you close over a variable outside of the scope of a lambda, and then change that variable after defining the anonymous method (but before invoking it) then you will see the changed value when you do invoke it).
So, what's the point of all of that. Well, if you were to close over this for a struct, which is a value type, it's possible for the lambda to outlive the struct. The anonymous method will be in a class, not a struct, so it will go on the heap, live as long as it needs to, and you are free to pass a reference to that class (directly or indirectly) wherever you want.
Now imagine that we have a local variable, with a struct of the type you've defined here. We use this named method to generate a lambda, and let's assume for a moment that the query items is returned (instead of the method being void). Would could then store that query in another instance (instead of local) variable, and iterate over that query some time later on another method. What would happen here? In essence, we would have held onto a reference to a value type that was on the stack once it is no longer in scope.
What does that mean? The answer is, we have no idea. (Please look over the link; it's kinda the crux of my argument.) The data could just happen to be the same, it could have been zeroed out, it could have been filled by entirely different objects, there is no way of knowing. C# goes to great lengths, as a language, to prevent you from doing things like this. Languages such as C or C++ don't try so hard to stop you from shooting your own foot.
Now, in this particular case, it's possible that you aren't going to use the lambda outside of the scope of what this refers to, but the compiler doesn't know that, and if it lets you create the lambda it has no way of determining whether or not you expose it in a way that could result in it outliving this, so the only way to prevent this problem is to disallow some cases that aren't actually problematic.

Why can '=' not be overloaded in C#?

I was wondering, why can't I overload '=' in C#? Can I get a better explanation?
Memory managed languages usually work with references rather than objects. When you define a class and its members you are defining the object behavior, but when you create a variable you are working with references to those objects.
Now, the operator = is applied to references, not objects. When you assign a reference to another you are actually making the receiving reference point to the same object that the other reference is.
Type var1 = new Type();
Type var2 = new Type();
var2 = var1;
In the code above, two objects are created on the heap, one referred by var1 and the other by var2. Now the last statement makes the var2 reference point to the same object that var1 is referring. After that line, the garbage collector can free the second object and there is only one object in memory. In the whole process, no operation is applied to the objects themselves.
Going back to why = cannot be overloaded, the system implementation is the only sensible thing you can do with references. You can overload operations that are applied to the objects, but not to references.
If you overloaded '=' you would never be able to change an object reference after it's been created.
... think about it - any call to theObjectWithOverloadedOperator=something inside the overloaded operator would result in another call to the overloaded operator... so what would the overloaded operator really be doing ? Maybe setting some other properties - or setting the value to a new object (immutability) ?
Generally not what '=' implies..
You can, however, override the implicit & explicit cast operators:
http://www.blackwasp.co.uk/CSharpConversionOverload.aspx
Because it doesn't really make sense to do so.
In C# = assigns an object reference to a variable. So it operates on variables and object references, not objects themselves. There is no point in overloading it depending on object type.
In C++ defining operator= makes sense for classes whose instances can be created e.g. on stack because the objects themselves are stored in variables, not references to them. So it makes sense to define how to perform such assignment. But even in C++, if you have set of polymorphic classes which are typically used via pointers or references, you usually explicitly forbid copying them like this by declaring operator= and copy constructor as private (or inheriting from boost::noncopyable), because of exactly the same reasons as why you don't redefine = in C#. Simply, if you have reference or pointer of class A, you don't really know whether it points to an instance of class A or class B which is a subclass of A. So do you really know how to perform = in this situation?
Actually, overloading operator = would make sense if you could define classes with value semantics and allocate objects of these classes in the stack. But, in C#, you can't.
One possible explanation is that you can't do proper reference updates if you overload assignment operator. It would literally screw up semantics because when people would be expecting references to update, your = operator may as well be doing something else entirely. Not very programmer friendly.
You can use implicit and explicit to/from conversion operators to mitigate some of the seeming shortcomings of not able to overload assignment.
I don't think there's any really particular single reason to point to. Generally, I think the idea goes like this:
If your object is a big, complicated object, doing something that isn't assignment with the = operator is probably misleading.
If your object is a small object, you may as well make it immutable and return new copies when performing operations on it, so that the assignment operator works the way you expect out of the box (as System.String does.)
You can overload assignment in C#. Just not on an entire object, only on members of it. You declare a property with a setter:
class Complex
{
public double Real
{
get { ... }
set { /* do something with value */ }
}
// more members
}
Now when you assign to Real, your own code runs.
The reason assignment to an object is not replaceable is because it is already defined by the language to mean something vitally important.
It's allowed in C++ and if not careful , it can result in a lot of confusion and bug hunting.
This article explains this in great detail.
http://www.relisoft.com/book/lang/project/14value.html
Because shooting oneself in the foot is frowned upon.
On a more serious note one can only hope you meant comparison rather than assignment. The framework makes elaborate provision for interfering with equality/equivalence evaluation, look for "compar" in help or online with msdn.
Being able to define special semantics for assignment operations would be useful, but only if such semantics could be applied to all situations where one storage location of a given type was copied to another. Although standard C++ implements such assignment rules, it has the luxury of requiring that all types be defined at compile time. Things get much more complicated when Reflection and and generics are added to the list.
Presently, the rules in .net specify that a storage location may be set to the default value for its type--regardless of what that type is--by zeroing out all the bytes. They further specify that any storage location can be copied to another of the same type by copying all the bytes. These rules apply to all types, including generics. Given two variables of type KeyValuePair<t1,t2>, the system can copy one to another without having to know anything but the size and alignment requirements of that type. If it were possible for t1, t2, or the type of any field within either of those types, to implement a copy constructor, code which copied one struct instance to another would have to be much more complicated.
That's not to say that such an ability offer some significant benefits--it's possible that, were a new framework being designed, the benefits of custom value assignment operators and default constructors would exceed the costs. The costs of implementation, however, would be substantial in a new framework, and likely insurmountable for an existing one.
This code is working for me:
public class Class1
{
...
public static implicit operator Class1(Class2 value)
{
Class1 result = new Class1();
result.property = value.prop;
return result;
}
}
Type of Overriding Assignment
There are two type to Override Assignment:
When you feel that user may miss something, and you want force user to use 'casting'
like float to integer, when you loss the floating value
int a = (int)5.4f;
When you want user to do that without even notice that s/he changing the object type
float f = 5;
How to Override Assignment
For 1, use of explicit keyword:
public static explicit override ToType(FromType from){
ToType to = new ToType();
to.FillFrom(from);
return to;
}
For 2, use of implicit keyword:
public static implicit override ToType(FromType from){
ToType to = new ToType();
to.FillFrom(from);
return to;
}
Update:
Note: that this implementation can take place in either the FromType or ToType class, depending on your need, there's no restriction, one of your class can hold all the conversions, and the other implements no code for this.

Create object instance without invoking constructor?

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.
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.
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.
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.
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;
}
}
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.
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.
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.
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.)
See the System.Activator.CreateInstance function.
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.
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.
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)

Categories

Resources