Confusion Regarding Default Constructor - c#

using System;
class Test
{
string name;
int num1, num2;
public Test()
{
num1=10;
num2=20;
}
public void Show()
{
Console.WriteLine(num1+num2);
Console.WriteLine(name);
}
}
class TestDemo
{
static void Main()
{
Test ob = new Test();
ob.Show();
}
}
Confusion:
The Complete Reference C# 3.0 says that a default constructor will not be called if you define your own constructor. I did that thing, but left the string variable without initializing it with my defined constructor. Now according to above concept the string variable is not initialized and no default constructor will run to give it a default value because I have defined my own.
So, why it does not show an error, that string is not initialized with any value or something similar. Doesn't it show that it has been assigned a value from somewhere [default constructor of compiler]?

There's no such thing as an "uninitialized" field (whether static or instance). All fields are initialized with a default value (null for reference types, the "natural zero" for value types).
The compiler will give you a warning if you include a readonly field which isn't assigned a value in the constructor, as then it will always have that default value - but it's still initalized.
The compiler can only spot when a local variable is used without being definitely assigned. That's because the compiler has a lot more information about control flow within a method than between methods within a class. If you have one method which assigns a value to a field and another which fetches the value from the field, there's no way for the compiler to know which will be called first - whereas the rules of definite assignment allow it to analyze a method to spot potential flows where a variable is read without having been assigned a value first.
None of this really has anything to do with default constructors, by the way. The compiler only provides a default constructor if you don't provide any constructors at all - so in your Test class, there's no default constructor as such, because you've provided your own parameterless constructor. Even if the compiler did provide a default constructor, it would be exactly equivalent to:
public Test() {}
... the fields would still just have their default values.

Your constructor
public Test()
{
num1=10;
num2=20;
}
is same as
public Test()
{
}
If you want to initialize num1 and num2 , you can do it as below:
private int num1, num2; //public fields are not recommended
public Test(int numberOne, int numberTwo)
{
num1 = numberOne;
num2 = numberTwo;
}
and you can do initialization as below:
Test ob = new Test(10,20);

Related

Why are we allowed to use const with reference types if we may only assign null to them?

The question is actually very straightforward. The following code throws the exception right below it:
class Foo
{
public const StringBuilder BarBuilder = new StringBuilder();
public Foo(){
}
}
Error:
Foo.BarBuilder' is of type 'System.Text.StringBuilder'. A const field
of a reference type other than string can only be initialized with
null.
MSDN says this, which I understand and it makes sense from const perspective:
A constant expression is an expression that can be fully evaluated at
compile time. Therefore, the only possible values for constants of
reference types are string and a null reference.
However, I don't see the reason why or where we would use null constant. So why in the first place that a reference type (other than string) can be defined with const if it can be only set to null and if it was a deliberate decision (which I believe it is) then where can we use constant with null values?
Update:
When we think of an answer, please let's think differently than "We have this so why not that..." context.
From MSDN
when the compiler encounters a constant identifier in C# source code (for example, months), it substitutes the literal value directly into the intermediate language (IL) code that it produces. Because there is no variable address associated with a constant at run time, const fields cannot be passed by reference and cannot appear as an l-value in an expression.
Because reference types (other than null, and strings which are special) need to be constructed at run time, the above would not be possible for reference types.
For reference types, the closest you can get is static readonly:
class Foo
{
// This is not a good idea to expose a public non-pure field
public static readonly StringBuilder BarBuilder = new StringBuilder();
public Foo(){
}
}
Unlike const substitution (in the calling code), static readonly creates a single shared instance of the reference type which has subtle differences if assembly versions are changed.
Although the reference cannot (normally) be reassigned, it doesn't preclude calling non-pure methods on the StringBuilder (like Append etc). This is unlike consts, where value types and strings are immutable (and arguably should be "eternal").
However, I don't see the reason why or where we would use null constant.
Null constants are useful as sentinel values.
For example, this:
public class MyClass
{
private const Action AlreadyInvoked = null;
private Action _action;
public MyClass(Action action) {
_action = action;
}
public void SomeMethod()
{
_action();
_action = AlreadyInvoked;
}
public void SomeOtherMethod()
{
if(action == AlreadyInvoked)
{
//...
}
}
}
Is much more expressive than this:
public class MyClass
{
//...
public void SomeMethod()
{
_action();
_action = null;
}
public void SomeOtherMethod()
{
if(action == null)
{
//...
}
}
}
The source code for the Lazy<T> class shows Microsoft used a similar strategy. Although they used a static readonly delegate that can never be invoked as a sentinel value, they could have just used a null constant instead:
static readonly Func<T> ALREADY_INVOKED_SENTINEL = delegate
{
Contract.Assert(false, "ALREADY_INVOKED_SENTINEL should never be invoked.");
return default(T);
};
As you state in the question, there is one reference type that can be put into a const reference - strings. The compiler special-cases this and puts the strings into the compiled output and allows them to be read into the reference type at runtime.
Of course this begs the question - why not have strings be the only reference types that can be const, as long as we're special-casing them anyway? To that, I can only speculate that adding a special case in the compiler is simpler and less problematic than adding a special case in the language. From a language perspective, a string is just a reference type, even if the compiler has special handling to create instances of it from string literals and compiled resources.
I think that you are asking that why reference type with null allow as a constant.
I think you are right that it does not make much sense but it is useful if you have designed your own library and if you want to compare with null but want to give special meaning ( like comparing with your library value only rather then directly null)
public class MyClass
{
public const MyClass MyClassNull = null;
public MyClass()
{
}
}
it usage like this.
object obj = GetMyClass();
if(obj == MyClass.MyClassNull) // This going to convert to actual null in MSIL.
{
}

Best way to use Value types as Reference types?

I've been using something similar to this whenever I needed to reference a Value type:
public class RefHost<T> {
public RefHost(T val)
{
Value = val;
}
private T _value;
public T Value {
get {
return _value;
}
set {
_value = value;
}
}
}
What I'm wondering is there a built in way or an easier way to use an existing Value type as a Reference type?
Example:
public class Editor {
public RefHost<int> Blah = new RefHost<int>(5);
// Some kind of timer to increase the value of Blah every few ticks
}
Kind of like that where the user of Editor specifies a value type that needs to be changed, and there can be multiple instances of Editor each with it's own value. I used the timer as an example but most of the time it's a user control like a slider.
I think you are looking for Tuple.
Sure there is. If you want to pass it as a reference type to a method just use the ref modifier:
public static void Main()
{
int n = 1;
Test(ref n);
Console.WriteLine(n); //will print out 2 and not 1.
Console.ReadKey(true);
}
public static void Test(ref int x)
{
x = 2;
}
What's wrong with this?
public class Editor {
public int Blah = 5;
// Some kind of timer, with a handler like:
void MyTimerTicker(object sender, EventArgs e)
{
this.Blah += 1;
}
}
Boxing and unboxing is what this is called. Your solution might be more type safe though.
See http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
Replace the property and backing field with a public field. While it is generally good for classes to use properties rather than fields, the whole purpose of your type is to be a simple mutable container for a single value-type instance; the state encapsulated by any reference to an instance of the type should be precisely defined by two things:
The value of the `Value` member
The whereabouts of all other references to the instance that exist anywhere in the universe
If two instances have the same Value, and if within the entire universe only one reference exists to each one, the two references should be semantically indistinguishable [since in both cases the set of "other references" that exist to the instances would be empty]
While there are various helper methods that a type of that style might implement, it would be impossible for a future version of the type to add additional state without violating the expected semantics. Since the whole purpose of the type is to behave like a class object containing a single field of type T, code will be clearest if one writes the object to in fact be a class object containing a single field of type T.
BTW, if you don't want to define a custom type, another option is to use a single-element T[1]. That will use a little bit of extra storage to hold the dimension, and adding [0] to all references will be a little uglier than .Value, but such an approach will nonetheless work pretty simply.

C# - Calling a struct constructor that has all defaulted parameters

I ran into this issue today when creating a struct to hold a bunch of data. Here is an example:
public struct ExampleStruct
{
public int Value { get; private set; }
public ExampleStruct(int value = 1)
: this()
{
Value = value;
}
}
Looks fine and dandy. The problem is when I try to use this constructor without specifying a value and desiring to use the defaulted value of 1 for the parameter:
private static void Main(string[] args)
{
ExampleStruct example1 = new ExampleStruct();
Console.WriteLine(example1.Value);
}
This code outputs 0 and does not output 1. The reason is that all structs have public parameter-less constructors. So, like how I'm calling this() my explicit constructor, in Main, that same thing occurs where new ExampleStruct() is actually calling ExampleStruct() but not calling ExampleStruct(int value = 1). Since it does that, it uses int's default value of 0 as Value.
To make matters worse, my actual code is checking to see that int value = 1 parameter is within a valid range within the constructor. Add this to the ExampleStruct(int value = 1) constructor above:
if(value < 1 || value > 3)
{
throw new ArgumentException("Value is out of range");
}
So, as it stands right now, the default constructor actually created an object that is invalid in the context I need it for. Anyone know how I can either:
A. Call the ExampleStruct(int value = 1) constructor.
B. Modify how the default values are populated for the ExampleStruct() constructor.
C. Some other suggestion/option.
Also, I am aware that I could use a field like this instead of my Value property:
public readonly int Value;
But my philosophy is to use fields privately unless they are const or static.
Lastly, the reason I'm using a struct instead of a class is because this is simply an object to hold non-mutable data, should be fully populated when it is constructed, and when passed as a parameter, should not be able to be null (since it is passed by value as a struct), which is what struct's are designed for.
Actually, MSDN has some good guidance on struct
Consider defining a structure instead of a class if instances of the
type are small and commonly short-lived or are commonly embedded in
other objects.
Do not define a structure unless the type has all of the following
characteristics:
It logically represents a single value, similar to primitive types
(integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
It will not have to be boxed frequently.
Notice that they are considerations for considering a struct, and its never a "this should always be a struct". That is because the choice to use a struct can have performance and usage implications (both positive and negative) and should be chosen carefully.
Notice in particular that they don't recommend struct for things > 16 bytes (then the cost of copying becomes more expensive than copying a reference).
Now, for your case, there is really no good way to do this other than to create a factory to generate a struct for you in a default state or to do some sort of trick in your property to fool it into initializing on first use.
Remember, a struct is supposed to work such that new X() == default(X), that is, a newly constructed struct will contain the default values for all fields of that struct. This is pretty evident, since C# will not let you define a parameterless constructor for a struct, though it is curious that they allow all arguments to be defaulted without a warning.
Thus, I'd actually suggest you stick with a class and make it immutable and just check for null on the methods that it gets passed to.
public class ExampleClass
{
// have property expose the "default" if not yet set
public int Value { get; private set; }
// remove default, doesn't work
public ExampleStruct(int value)
{
Value = value;
}
}
However, if you absolutely must have a struct for other reasons - but please consider the costs of struct such as copy-casts, etc - you could do this:
public struct ExampleStruct
{
private int? _value;
// have property expose the "default" if not yet set
public int Value
{
get { return _value ?? 1; }
}
// remove default, doesn't work
public ExampleStruct(int value)
: this()
{
_value = value;
}
}
Notice that by default, the Nullable<int> will be null (that is, HasValue == false), thus if this is true, we didn't set it yet, and can use the null-coalescing operator to return our default of 1 instead. If we did set it in the constructor, it will be non-null and take that value instead...
I don't think it's good design to have a struct ExampleStruct such that
default(ExampleStruct)
i.e. the value where all instance fields are zero/false/null, is not a valid value of the struct. And as you know, when you say
new ExampleStruct()
that's exactly the same as default(ExampleStruct) and gives you the value of your struct where all fields (including "generated" fields from auto-properties) are zero.
Maybe you could do this:
public struct ExampleStruct
{
readonly int valueMinusOne;
public int Value { get { return valueMinusOne + 1; } }
public ExampleStruct(int value)
{
valueMinusOne = value - 1;
}
}
I guess the compiler is actually picking the automatic default ctor for structs here http://msdn.microsoft.com/en-us/library/aa288208(v=vs.71).aspx, rather than using your ctor with the default values.
added references:
http://csharpindepth.com/Articles/General/Overloading.aspx (Optional parameters section)
Although some languages (CIL if nothing else) will allow one to define a struct constructor such that new T() has fields set to something other than their "all zeroes" defaults, C# and vb.net (and probably most other languages) take the view that since things like array elements and class fields must always be initialized to default(T), and since having them be initialized to something which didn't match new T() would be confusing, structures shouldn't define new T() to mean something other than default(T).
I would suggest that rather than trying to jinx a default parameter in a parameterized constructor, you simply define a static struct property which returns your desired default value, and replace every occurrence of new ExampleStruct() with ExampleStruct.NiceDefault;.
2015 Addendum
It appears that C# and VB.NET may ease the prohibition against defining parameterless struct constructors. This may cause a statement like Dim s = New StructType() to assign s a value which is different from the value given to new array items of type StructType. I'm not terribly keen on the change, given that new StructType is often used in places where something analogous to C#'s default(StructType) would be more appropriate if it existed. VB.NET would allow Dim s As StructType = Nothing, but that seems rather hokey.
why do you have public ExampleStruct(int value = 1) : this() ?
shouldn't it be public ExampleStruct(int value = 1)? I think the :this() is creating the no-parameter constructor.

Explicitly refer to a parameter

How do I explicitly refer to the parameter as opposed to the member variable?
static recursive{
public static List<string> output = new List<string>();
public static void Recursive(List<string> output){
...
}
}
An unqualified reference will always refer to the parameter because it is at a more local scope.
If you want to refer to the member variable, you need to qualify it with the name of the class (or this, for non-static member variables).
output = foo; // refers to the parameter
recursive.output = foo; // refers to a static member variable
this.output = foo; // refers to a non-static member variable
But you should probably change the name anyway. It makes your code much easier to read.
And you shouldn't have public static variables at all. All of the .NET coding style guidelines strongly recommend properties instead of exposing public fields. And since those are always camel-cased, this problem solves itself.
public static void Recursive(List<string> output){
...
}
The code in the block that refers to output will always be local & not the member variable.
If you wish to refer to member variable, you could use recursive.output.
When you are inside the Recursive static method output will point to the argument of the method. If you want to point to the static field use the name of the static class as prefix: recursive.output
Give your member variable another name.
The convention is to use Camelcasing on public static members.
public static List<string> Output = new List<string>();
public static void Recursive( List<string> output )
{
Output = output;
}
You can explicitly reference recursive.output to indicate the static member, but it would be cleaner to rename either the parameter or the member.
I know of no way to explicitly refer to a parameter. The way this is usually handled is to give member variables a special prefix such as _ or m_ so that parameters will never have exactly the same name. The other way is to refer to member variables using this.var.
public class MyClass {
public int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(number); // prints value of "number" parameter
}
}
EDIT::
For static fields is required name of class instead of "this":
public class MyClass {
public static int number = 15;
public void DoSomething(int number) {
Console.WriteLine(this.number); // prints value of "MyClass.number"
Console.WriteLine(MyClass.number); // prints value of "number" parameter
}
}

Why use the 'ref' keyword when passing an object?

If I am passing an object to a method, why should I use the ref keyword? Isn't this the default behaviour anyway?
For example:
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t.Something = "Bar";
}
}
public class TestRef
{
public string Something { get; set; }
}
The output is "Bar" which means that the object was passed as a reference.
Pass a ref if you want to change what the object is:
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(ref t);
void DoSomething(ref TestRef t)
{
t = new TestRef();
t.Something = "Not just a changed t, but a completely different TestRef object";
}
After calling DoSomething, t does not refer to the original new TestRef, but refers to a completely different object.
This may be useful too if you want to change the value of an immutable object, e.g. a string. You cannot change the value of a string once it has been created. But by using a ref, you could create a function that changes the string for another one that has a different value.
It is not a good idea to use ref unless it is needed. Using ref gives the method freedom to change the argument for something else, callers of the method will need to be coded to ensure they handle this possibility.
Also, when the parameter type is an object, then object variables always act as references to the object. This means that when the ref keyword is used you've got a reference to a reference. This allows you to do things as described in the example given above. But, when the parameter type is a primitive value (e.g. int), then if this parameter is assigned to within the method, the value of the argument that was passed in will be changed after the method returns:
int x = 1;
Change(ref x);
Debug.Assert(x == 5);
WillNotChange(x);
Debug.Assert(x == 5); // Note: x doesn't become 10
void Change(ref int x)
{
x = 5;
}
void WillNotChange(int x)
{
x = 10;
}
You need to distinguish between "passing a reference by value", and "passing a parameter/argument by reference".
I've written a reasonably long article on the subject to avoid having to write carefully each time this comes up on newsgroups
In .NET when you pass any parameter to a method, a copy is created. In value types means that any modification you make to the value is at the method scope, and is lost when you exit the method.
When passing a Reference Type, a copy is also made, but it is a copy of a reference, i.e. now you have TWO references in memory to the same object. So, if you use the reference to modify the object, it gets modified. But if you modify the reference itself - we must remember it is a copy - then any changes are also lost upon exiting the method.
As people have said before, an assignment is a modification of the reference, thus is lost:
public void Method1(object obj) {
obj = new Object();
}
public void Method2(object obj) {
obj = _privateObject;
}
The methods above does not modifies the original object.
A little modification of your example
using System;
class Program
{
static void Main(string[] args)
{
TestRef t = new TestRef();
t.Something = "Foo";
DoSomething(t);
Console.WriteLine(t.Something);
}
static public void DoSomething(TestRef t)
{
t = new TestRef();
t.Something = "Bar";
}
}
public class TestRef
{
private string s;
public string Something
{
get {return s;}
set { s = value; }
}
}
Since TestRef is a class (which are reference objects), you can change the contents inside t without passing it as a ref. However, if you pass t as a ref, TestRef can change what the original t refers to. i.e. make it point to a different object.
With ref you can write:
static public void DoSomething(ref TestRef t)
{
t = new TestRef();
}
And t will be changed after the method has completed.
Think of variables (e.g. foo) of reference types (e.g. List<T>) as holding object identifiers of the form "Object #24601". Suppose the statement foo = new List<int> {1,5,7,9}; causes foo to hold "Object #24601" (a list with four items). Then calling foo.Length will ask Object #24601 for its length, and it will respond 4, so foo.Length will equal 4.
If foo is passed to a method without using ref, that method might make changes to Object #24601. As a consequence of such changes, foo.Length might no longer equal 4. The method itself, however, will be unable to change foo, which will continue to hold "Object #24601".
Passing foo as a ref parameter will allow the called method to make changes not just to Object #24601, but also to foo itself. The method might create a new Object #8675309 and store a reference to that in foo. If it does so, foo would no longer hold "Object #24601", but instead "Object #8675309".
In practice, reference-type variables don't hold strings of the form "Object #8675309"; they don't even hold anything that can be meaningfully converted into a number. Even though each reference-type variable will hold some bit pattern, there is no fixed relationship between the bit patterns stored in such variables and the objects they identify. There is no way code could extract information from an object or a reference to it, and later determine whether another reference identified the same object, unless the code either held or knew of a reference that identified the original object.
This is like passing a pointer to a pointer in C. In .NET this will allow you to change what the original T refers to, personally though I think if you are doing that in .NET you have probably got a design issue!
By using the ref keyword with reference types you are effectively passing a reference to the reference. In many ways it's the same as using the out keyword but with the minor difference that there's no guarantee that the method will actually assign anything to the ref'ed parameter.
ref mimics (or behaves) as a global area just for two scopes:
Caller
Callee.
If you're passing a value, however, things are different. You can force a value to be passed by reference. This allows you to pass an integer to a method, for example, and have the method modify the integer on your behalf.

Categories