This question already has answers here:
Bodyless constructor in non-abstract C# class
(2 answers)
Closed 6 years ago.
I saw a code similar to what mentioned below :
public class SomeClass : AnotherClass
{
public SomeClass();
.
.
.
.
}
So what is the meaning of the following line of code in this, what does it do ?
public SomeClass();
Code I am referring to.
that is the constructor of the class SomeClass, and you can use it (call it) everytime you need to create a new object (AKA instance) of the class SomeClass
take a look at how to use a constructor (Thanks to CrowCoder for the comment) and if required take a look at the constructors doc
Instance constructors are used to create and initialize any instance
member variables when you use the new expression to create an object
of a class. To initialize a static class, or static variables in a
non-static class, you must define a static constructor. For more
information, see Static Constructors (C# Programming Guide).
What you are referencing is called a Constructor. Constructors have the same name as the class, and they are used to initialize data members of the new object.
Please reference.
Whenever a class or struct is created, its constructor is called. A class or struct may have multiple constructors that take different arguments. Constructors enable the programmer to set default values, limit instantiation, and write code that is flexible and easy to read.
If you saw code similar to what you mentioned, then honestly that would cause a compile time error, since the syntax for that default constructor (taking 0 parameters) is incorrect.
Needs to be:
public SomeClass()
{
//initialize members;
}
If you retrieved the code that you just posted a picture of, by hitting Go To Definition of the class, then it will only show declarations, and not implementation.
Related
This question already has answers here:
Is the "textual order" across partial classes formally defined?
(2 answers)
Closed 1 year ago.
Lots of answers for similar questions seem to always be about static classes. This is about instance fields.
Suppose I have this
// File.cs
public partial class Stuff
{
public Stuff()
{
obj.DoSomething();
}
}
// OtherFile.cs
public partial class Stuff
{
MyObject obj = new MyObject("test");
}
Is this guaranteed to be safe? Like it won't do, for example, field initialization and run the constructor in one class, and then do the field initialization in the other part?
Does the C# language guarantee this will always be safe?
Note: Is the "textual order" across partial classes formally defined? does not answer the question. The answer for the current question gives an answer that is not part of such a question. It should not be linked as a duplicate to this particular link.
Yes, because partial classes are still compiled into one class. The partial syntax feature just lets you split the definition of a class into multiple files. There are no "parts" as far as the compiled type is concerned.
So all sequencing regarding static and non-static constructors, initializers, etc. still hold.
I can imagine the first reaction when you read the title of my question: "How can you have such a high reputation here and ignore what a class is?"
My point is the following: until now I have always worked with C++, Delphi, Java, ... and there it's quite simple: a class is a type definition of an object. You need to reserve some space in memory to start using it (hence the constructor) and afterwards, don't forget to free that memory (if your programming language does not support garbage collection).
Today, however, I had a problem concerning type definitions and constants in C#, and I fell on this URL, mentioning such pieces of source code:
class Calendar1
{
public const int Months = 12;
}
In order to use this, you just need to do:
using Calendar1;
And you can use Months as a constant.
But here's my question: where's the constructor? If this class is the type definition of an object, which object are we talking about?
So, if I understand correctly, C# is based on the idea "Everything is a class", but in order to make this work, the C# inventors have extended the definition of a class, so now we get (C# definition):
A class is one of the following:
a type definition for an object. In that case, a constructor is needed for creating the object.
...
Can somebody finish the definition?
This is a pretty common practice in C#. Classes are often used to create "sacks" to hold constants, or commonly as a entity or dto object. These are usually made without a user defined constructor. If a class does not have a constructor, one is defined at compile time which amounts to an empty constructor:
public Calendar1()
{
}
This answer goes into much further detail:
C# class without constructor
You don't need this using. using is to make namespaces available.
A constant is static. This means that it is not an instance member but a member of the type. Thus, you can access it through the type name: Calendar1.Months or, with a using static Calendar1; just with Months.
In C# a class implicitly creates a parameterless public constructor, if you don't declare one explicitly.
When you are creating a instance of a class you are allocating memory (using the keyword new)
Constants are created not in runtime, they are created in compile time and stored in the assembly metadata. So when you are accessing a constant you will be not accessing an instance of a class - you will be accessing the constant from the metadata directly.
Have a look at this post:
How are C# const members allocated in memory?
I am trying to use a class that unfortunately does not have a constructor defined. When I try to create the object C# tells me that there is no predefined constructor. I was told that this class was created in Visual Basic 6 many years ago, and that somehow in VB the constructor was not needed.
Can anyone think of any solutions for this problem. Maybe a I could declare a new class and inherit the old one. Then in the new class I could create the constructor.
someClass myClass= new someClass();
//Returns an error saying no constructor can be found at all.
It might have an internal constructor. See this answer. This would mean you won't be able to access the constructor from a different assembly. (See MSDN.)
There might be some method in that assembly that instantiates an instance of that class. Try finding a method like that, and call it to get an instance of someClass.
I'm trying to build a generic class whose constructor introduces an additional type, but the compiler says no-no.
I don't quite understand why the following doesn't work:
public class Foo<T>
{
public Foo<T,TBar>(TBar tBar)
{
...
}
}
It's not critical as I can write the class using a fluent api (which might be preferred), but I'd still like to understand why I can't. The only explanation I can think of is that the compiler doesn't like method-level generic type declaration mixed with class-level generic type declaration.
It is not possible. The constructor is not called like a method, it is invoked by specifying the class name only (after the new keyword). Normal methods, on the other hand, can have additional generic type arguments.
No. Only types and methods can be generic. You can't have generic properties, events, fields, constructors or finalizers.
Note that this has nothing to do with whether the containing type is generic or not - it's just a limitation of the language (and CLR, I suspect), basically. (Interestingly, Java does allow generic constructors - but generics in Java are pretty different to those in C# anyway.)
It is not directly possible, as Jon himself pointed out, but there is a common workaround, that solves the problem:
public class Foo<T,TBar>
{
public Foo(TBar tBar)
{
//do something
}
}
IIUC, the call to new for this is just as you wanted it
A constructor is a special method. Have you ever noticed the parantheses coming after the name of the class and the new keyword?
Person jack = new Person();
The Person(); has a method call syntax. This is because it's not the type Person, but a method named exactly as the type itself, due to the design of the language to be called to initialize the type.
Quoting from C# specification:
The identifier of a constructor-declarator shall name the class in which the instance constructor is declared. If any other name is specified, a compile-time error occurs.
and
17.10 Instance constructors
An instance constructor is a member that implements the actions required to initialize an instance of a class. Instance constructors are declared using constructor-declarations:
And if you look at the constructor formula, you don't see any generic declaration token at all:
constructor-declarator:
identifier ( formal-parameter-listopt ) constructor-initializeropt
This is more of a documentation than a real question. This does not seem to have been addressed on SO yet (unless I missed it), so here goes:
Imagine a generic class that contains a static member:
class Foo<T> {
public static int member;
}
Is there a new instance of the member for each specific class, or is there only a single instance for all Foo-type classes?
It can easily be verified by code like this:
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
What is the result, and where is this behavior documented?
A static field is shared across all instances of the same type. Foo<int> and Foo<string> are two different types. This can be proven by the following line of code:
// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));
As for where this is documented, the following is found in section 1.6.5 Fields of the C# Language Specification (for C# 3):
A static field identifies exactly one
storage location. No matter how many
instances of a class are created,
there is only ever one copy of a
static field.
As stated before; Foo<int> and Foo<string> are not the same class; they are two different classes constructed from the same generic class. How this happens is outlined in section 4.4 of the above mentioned document:
A generic type declaration, by itself,
denotes an unbound generic type that
is used as a “blueprint” to form many
different types, by way of applying
type arguments.
The problem here is actually the fact that "generic classes" are not classes at all.
Generic class definitions are just templates for classes, and until their type parameters are specified, they are just a piece of text (or a handful of bytes).
At runtime, one can specify a type parameter for the template, thus bringing it to life, and creating a class of the, now, fully specified type. That's why static properties are not template-wide, and that's why you cannot cast between List<string> and List<int>.
That relationship kinda mirrors the class-object relationship. Just like classes do not exist* until you instantiate an object from them, generic classes do not exist, until you make a class based on the template.
P.S. It's quite possible to declare
class Foo<T> {
public static T Member;
}
From this is kinda obvious that the static members cannot be shared, as T is different for different specializations.
They are not shared. Not sure where it's documented but analysis warning CA1000 (Do not declare static members on generic types) warns against just this due to the risk of making the code more complicated.
C# implementation of generics is more closer to C++. In both of these languages MyClass<Foo> and MyClass<Bar> don't share static members but in Java they do. In C# and C++ MyClass<Foo> internally creates entirely new type at compile time as if generics are kind of macros. You can usually see their generated names in stack trace, like MyClass'1 and MyClass'2. This is why they don't share static variables. In Java, generics are implemented by more simpler method of compiler generating code using non-generic types and adding type casts all over. So MyClass<Foo> and MyClass<Bar> don't generate two entirely new class in Java, instead they both are same class MyClass underneath and that's why they share static variables.
They are not really shared.
Because the member doesn't belong to the instance at all.
A static class member belongs to the class itself.
So, if you have MyClass.Number it is the same for all MyClass.Number objects because it not even depends on the object.
You can even call or modify MyClass.Number without any object.
But since Foo< int > is not the same class as Foo< string > these two numbers are not shared.
An example to show this:
TestClass<string>.Number = 5;
TestClass<int>.Number = 3;
Console.WriteLine(TestClass<string>.Number); //prints 5
Console.WriteLine(TestClass<int>.Number); //prints 3
IMO, you need to test it, but I think that
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
will output 1 because I think that, during compilation, the compilator create 1 class for every generic class you use (in you example : Foo<int> and Foo<string>).
But I'm not 100% sure =).
Remark : I think it's not a good design nor a good practice to use such kind of static attributes.