Since the C# Array class is abstract, how is it instantiated? - c#

I just started to learn C# and I came across the fact that Array is an abstract class, not a concrete one. I am wondering how it is possible that array instances can be created if it is declared as abstract in the documentation (as seen in https://learn.microsoft.com/en-us/dotnet/api/system.array?view=net-5.0).

'Array' is an abstract class, so it cannot be instantiated directly. However it has an static 'CreateInstance' method, which creates an instance of a concrete implementation of an array containing elements of the required type.
see https://learn.microsoft.com/en-us/dotnet/api/system.array.createinstance?view=net-5.0#System_Array_CreateInstance_System_Type_System_Int32_
and also: Difference between Array.CreateInstance and using the new operator to create new array instance

Related

What is a class?

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?

How do object type variables accept class type instance

I need to clarify a thing that how an object type variables accept class type instance an given in the below code snippet,
class MyClass
{
}
static void Main()
{
object obj = new MyClass();
}
Since the MyClass is not a type of object but still the instance of MyClass is accepted in the obj(object) variable.
Actually, your class is an object.
In C# all classes derives from object.
Referring to a class as it's base type is one way of Polymorphism.
It might be better understood using an analogy:
Your class is an object, like a Dog is an animal.
Also, If you try the following:
object obj = new MyClass();
bool isMyType = obj == typeof(MyClass); //<--this will be true.
Take a look at this SO thread for more information how Polymorphism can be useful.
The concept that you do not understand is polymorphism which basically say that you can define an is relation between your classes. For a simple logic every dog is an animal so you can have class Dog that inherits from Animal. This implies that you can assign to variable of type Animal an instance of a Dog but not the other way around - not every animal is a dog. Another thing is that every thing derives form object this is language concept that you simply can take for granted.
Evrything in c# is derived from Object...
even your class.
.Net follows OOPs (Object Oriented Programming Language) and here every class can act as a object. Every class inherits Object class and hence every class can act as an object. In your example, .Net creates a default constructor to create instance of the class. You can definitely write your own constructor there.
Hope it helps.
Everything in C# is derived from Object.
Even Value Types like struct(int,float,..) are all derived from Object type.
When you define your own class,it implicitly derives from the Object type.
It is mentioned in the docs
All classes, structures, enumerations, and delegates inherit from
Object class
MSDN:
Supports all classes in the .NET Framework class hierarchy and provides low-level
services to derived classes. This is the ultimate base class of all classes
in the .NET Framework; it is the root of the type hierarchy.
Inheritance Hierarchy:
All classes, structures, enumerations, and delegates.
This means when you use int.Parse() to cast some value to int, there is a class behind int type which makes it able to have methods and do such stuffs. Object has been rooted pretty much everywhere in .Net.

Converting from an interface to an object that implements the interface?

I have an interface which is implemented by several different objects. What I am trying to do is write a method in c# that will accept the interface object as a parameter and convert this parameter to an object that it implements so i don't have to write the same function for several different types. Such as:
Class UnappliedCashDetails implements interface ITransactionDetail.
Constructor for ISSBatch:
public ISSBatch(List<ITransactionDetail> details)
public static ISSBatch GetNextReceiptBatch()
{
List<UnappliedCashDetail> details = new List<UnappliedCashDetail>();
/`*`some code here to populate my list`*`/
return = new ISSBatch(details);
}
C# does not like this. Am i trying to use the interface wrong or just not casting correctly?
Thanks!
You're passing a List<UnappliedCashDetail> to a constructor that accepts List<ITransactionDetail>. UnappliedCashDetail may very well implement ITransactionDetail, but this type of variance is not supported by C#. Consider that inside the constructor (or any other method) you could attempt to add an instance of SomeOtherTransactionDetail to your details list, except that the details list should really only accept UnappliedCashDetail, as per its declaration.
To make your code work, you need to change your declaration
List<ITransactionDetail> details = new List<ITransactionDetail>();
/* some code here to populate my list */
return new ISSBatch(details);
Or you could simply change your constructor to accept IEnumerable<ITransactionDetail>, in which case your original List<UnappliedCashDetail> declaration would work. Variance is supported for IEnumerable<T> (note: C# 4), since it is just a sequence and cannot be added to, deleted from, etc., so there's no possibility of trying to add an AppliedCashDetail instance to a sequence of UnappliedCashDetail objects.

Are static members of a generic class tied to the specific instance?

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.

C# Member Access from Nested Class to Containing Class [duplicate]

This question already has answers here:
What's the best way of accessing field in the enclosing class from the nested class?
(9 answers)
Closed 10 years ago.
I have ClassB, which is nested inside of ClassA. In ClassA I have a variable called _MyId... how can I access _MyId from ClassB?
Thanks in advance!
Put simply, you'll need a reference to an instance ClassA within ClassB.
C#'s nested classes work differently from Java's, if that's what you're used to. The closest analog would be Java's static class when applied to a nested type (meaning that C#'s nested classes are not associated with a particular instance of the outer class).
In other words, C#'s nested classes are not "special" when compared to outer classes, other than the fact that they have visibility into the private members of the outer class. Nonetheless, you still need a reference to the outer class in order to access them.
In ClassB's constructor pass an instance of class A.
If the field is static, you can simply refer to it as ClassA._MyId. If it's not you should use classAInstance._MyId where classAInstance is an instance of ClassA.
If you're coming from Java background, you should note that nested classes in C# are similar to static nested classes in Java.
You have to refer to a particular instance of ClassA in order to retrieve a member. If your instance is called foo, just use foo._MyId.
If _MyId is static you can access it by it's name or as ClassA._MyId.
But otherwise you need an instance of ClassA first, and there is little difference with acces from another class (that is not nested). But members from ClassB do gain access to private members of ClassA.
Explanation: Nesting classes is a static relation between the 2 Types, there is no implicit relation between instances. You will have to pass references to objects between them just as if the classes were not nested.

Categories