Can a structure inherit from a class in .NET? - class

I am confused about inheritance in .NET and here is why.
I was previously of the understanding that a structure cannot inherit from a class in .NET, so for example, the following won't compile:
struct MyStruct : MyClass
{
}
But today I read that integers (and other value types) are structs and not objects and they inherit from the ValueType class. The ValueType class inherits from System.Object and its purpose is to override certain methods in System.Object to make these methods suitable for Value Types.
So what's the deal? Can a structure inherit from a class in .NET, can it not or can it only in certain circumstances?
Thanks

Within the guts of .net, the definition for a struct containing certain members is the same as a definition for a class which those same fields and members, and which inherits from System.ValueType. Note that compilers will not allow one to declare a class which inherits ValueType, but when one declares a struct, the compiler, "behind the scenes" declares a class which does.
What makes value types special in .net is the way the run-time allocates storage locations (variables, fields, parameters, etc.) When a storage location of a type not inheriting from ValueType is declared, the runtime will allocate space for a heap object reference. By contrast, when a storage location of a type inheriting from ValueType is declared, the runtime will allocate space for all the public and private fields of that type. For a type like int, the system allocates a private field which is of a special primitive type, outside the normal type system.
Note that a storage location of a value type doesn't really hold an instance of that type; instead is an instance of that type, and holds all of the fields of that type. A statement like struct1 = struct2 does not replace the value-type instance struct1 with the instance struct2. Instead, it copies all of the fields from struct2 over the corresponding fields in struct1. Likewise if a value-type storage location is passed as a method to a procedure without using the ref keyword, what is passed is not the struct instance itself, but rather the contents of its fields.
If it is necessary to copy a value-type storage location to a one of type not derived from ValueType (e.g. Object or IComparable), the system will create a new heap-object instance of the value type, copy all the fields from the value type to that new instancen and store a reference to that new instance in the target storage location. This process is called "boxing". Most compilers will do this implicitly, thus attempting to behave as though a value type storage location holds an object which derives from ValueType. It's important to note, though, that this is an illusion. If type X derives from Y, one has an X named xx and a Y named yy, and one performs xx = yy, such a statement should cause xx and yy to refer to the same object instance. That will happen if xx and yy are types not derived from ValueType, even if yy holds an instance of something derived from ValueType. It will not happen, however, if xx and/or yy derives from ValueType. In that case, the system will copy fields from one instance to another (possibly new) instance.

Related

Relation between Existential Container and struct instance which conform protocol

I'm trying to understand how to find protocol method's implementation.
I know that Swift uses an Existential Container for fixed-size storage in Stack memory which manages how to describe an instance of a struct in memory. and it has a Value Witness Table (VWT) and Protocol Witness Table (PWT)
VWTs know how to manage real value in instance of struct (their lifecycle) and PWTs know the implementation of protocol's method.
But I want know the relation between the instance of a struct and the "existential container".
Does an instance of struct have a pointer which refers to an existential container?
How does an instance of a struct know its existential container?
Preface: I don't know how much background knowledge you have, so I might over-explain to make sure my answer is clear.
Also, I'm doing this to the best of my ability, off by memory. I might mix up some details, but hopefully this answer could at least point you towards further reading.
See also:
https://stackoverflow.com/a/41490551/3141234
https://github.com/apple/swift/blob/main/docs/SIL.rst#id201
In Swift, protocols can be used "as a type", or as a generic constraint. The latter case looks like so:
protocol SomeProtocol {}
struct SomeConformerSmall: SomeProtocol {
// No ivars
}
struct SomeConformerBig: SomeProtocol {
let a, b, c, d, e, f, g: Int // Lots of ivars
}
func fooUsingGenerics<T: SomeProtocol>(_: T) {}
let smallObject = SomeConformerSmall()
let bigObject = SomeConformerBig()
fooUsingGenerics(smallObject)
fooUsingGenerics(bigObject)
The protocol is used as a constraint for type-checking at compile time, but nothing particularly special happens at runtime (for the most part). Most of the time, the compiler will produced monomorphized variants of the foo function, as if you had defined fooUsingGenerics(_: SomeConformerSmall) or fooUsingGenerics(_: SomeConformerBig) to begin with.
When a protocol is "used like a type", it would look like this:
func fooUsingProtcolExistential(_: SomeProtocol) {}
fooUsingGenerics(smallObject)
fooUsingGenerics(bigObject)
As you see, this function can be called using both smallObject and bigObject. The problem is that these two objects have different sizes. This is a problem: how will the compiler know how much stack space is necessary to allocate for the arguments of this function, if the arguments can be different sizes? It must do something to help fooUsingProtcolExistential accommodate that.
Existential containers are the solution. When you pass a value where a protocol type is expected, the Swift compiler will generate code that automagically boxes that value into an "existential container" for you. As currently defined, an existential container is 4 words in size:
The first word is a pointer to the Protocol Witness Table (more on this later)
The next three words are inline storage for the value.
When the value being stored is less than 3 words in size (e.g. SomeConformerSmall), the value is packed directly inline into that 3 word buffer. If the value is more than 3 words in size (e.g. SomeConformerSmall), a ARC-managed box is allocated on the heap, and the value is copied into there. A pointer to this box is then copied into the first word of the existential container (the last 2 words are unused, IIRC).
This introduces a new issue: suppose that fooUsingProtcolExistential wanted to forward along its parameter to another function. How should it pass the EC? fooUsingProtcolExistential doesn't know whether the EC contains a value-inline (in which case, passing the EC just entails copying its 4 words of memory), or heap-allocated (in which case, passing the EC also requires an ARC retain on that heap-allocated buffer).
To remedy this, the Protocol Witness Table contains a pointer to a Value Witness Table (VWT). Each VWT defines the a standard set of function pointers, that define how the EC can be allocated, copied, deleted, etc. Whenever a protocol existential needs to be manipulated in someway, the VWT defines exactly how to do so.
So now we have a constant-size container (which solves our heterogeneously-sized parameter passing problem), and a way to move the container around. What can we actually do with it?
Well at a minimum, values of this protocol type must at least define the required members (initializers, properties (stored or computed), functions and subscripts) that the protocol defines.
But each conforming type might implement these members in a different way. E.g. some struct might satisfy a method requirement by defining the method directly, but another class might satisfy it by inheriting the method from a superclass. Some might implement a property as a stored property, others as a computed property, etc.
Handling these incompatibilities is the primary purpose of the Protocol Witness Table. There's one of these tables per protocol conformance (e.g. one for SomeConformerSmall and one for SomeConformerBig). They contain a set of function pointers with point to the implementations of the protocols' requirements. While the pointed-to functions might be in different places, the PWT's layout is consistent for the protocol is conforms to. As a result, fooUsingProtcolExistential is able to look at the PWT of an EC, and use it to find the implementation of a protocol method, and call it.
So in short:
An EC contains a PWT and a value (inline or indirect)
A PWT points to a VWT
My understanding:
Struct doesn't know where existential container/value witness table/protocol witness table is, the compiler knows. If needed somewhere, compiler pass them to there.

Difference between objects, attributes, variables and class instance

I am having trouble understanding my professor's lecture notes because my brain seem to treat objects, attributes, variables and class instance as interchangeable. I really appreciate any help in distinguishing these 4 terms. Thank you!
this would be helpful for u Visit https://www.quora.com/What-is-the-difference-between-instance-variable-and-class-variable
Class variables are declared with keyword static and Instance variables are declared without static keyword.
Class variables are common to all instances of a class. These variables are shared between the objects of a class. Instance variables are not shared between the objects of a class. Each instance will have their own copy of instance variables.
As class variables are common to all objects of a class, changes made to these variables through one object will reflect in another. As each object will have its own copy of instance variables, changes made to these variables through one object will not reflect in another object.
Class variables can be accessed using either class name or object reference. Instance variables can be accessed only through object reference.
https://qph.fs.quoracdn.net/main-qimg-c4b92e80a8500c11fe705c1bafc3ed26
You don't mention the programming language at question.
Usually a class is a model or template that declares
how a certain category of objects look like.
You give a class a name and you mention if it inherits
members from another class or not.
You define also the class members.
These can be variables that hold data (object state)
and methods (class defined functions) that define
the object behaviour.
When you instantiate a class using the declared model
, you get an object, that is a concrete class instance.
This is a concrete entity, think of it as a new variable in memory,
whose data type is the class (instead of for example
integer or string data types), whose value is its state
in a defined moment in time (the state being the
combination of all of its data member variables values
at that moment). This object has to have an identity,
because it exists in memory and it is a different entity
from the other objects you can instantiate from this or
any other class. The data member variables hold specific
values for each instance. These are not shared between
instances.
Now the member methods can be shared between instances
because they have no state, so they are equal for every object.
They are called with some arguments
and they do some action that changes the object state, or
is at least tightly related with the concrete object.
But they are common to every object. The methods usually
know what concrete object they act upon by means of a special
name like 'this' or 'self', that references to 'itself'.
Objects are usually assigned to variables upon creation,
storing a reference to its identity that allows the
remaining code to manipulate them.
You use these variables to refer to the concrete object
outside the code of the classes, and use 'this' or 'self'
to refer to it from inside the classes.
Frequently you access object members qualifying with the
object name. Like in 'player.run()', or 'player.total_score'.
That is if player is a variable to which you assigned a
class Player instance. This can look like player = new Player
or player = Player().
Attributes is just another name given to data members.
Sometimes attributes and also methods can be public or private,
meaning code outside the class can use them, or only
the class code can have access.
Sometimes you see data members or attributes referred as
properties. When you access an attribute, you are accessing
a property. In some languages like Python, property can mean
something a little different but close related anyway...
Now also depending on the language things can be like described
(C++, Java) or you can have everything being treated as objects,
including the class definitions (Python).
You should also search the internet or SO about
inheritance, overriding, class diagrams, and other things class
related.
This is all no more than the ability of defining your own data types
beoynd the language builtin types.
You can think of variables as names for boxes (memory containers in a certain address) holding values. But sometimes you want to manipulate
not the values but the addresses themselves. This time you say you have
references (to addresses). Sometimes variables are just names for those
references. References are also known as pointers. But you could do math with pointers (increment, decrement, add a fixed value to...) that you usually don't do with references.

Are properties in a Swift class automatically references?

I have this class in which the properties are the class itself.
class Voxel {
var vertices : [Vertex] = []
var above : Voxel?
var below : Voxel?
var front : Voxel?
var back : Voxel?
var left : Voxel?
var right : Voxel?
}
It acts as a node in a Doubly 3D Linked List, but the thing is, in C and C++, I would have to store the neighbors as pointers (which I want to do to the vertex array as well).
Is this automatically done for me in Swift?
I don't see a fine way of holding an array of vertices as an array of pointers, and I certainly don't want to hold the actual values, as I'm going to have thousands of voxels.
Because Voxel is a class, a reference type, these are pointers. If it were a struct, it would be a value type and therefore each new reference would be a new copy.
By the way, be wary of strong reference cycles. Make sure one instance's implicit strong reference below is not another instance whose above is another strong reference back to the other instance. To resolve this, you'd make all of those references weak and then have some collection (e.g., a set or maybe an array or dictionary) which maintains strong references to all of the instances in the doubly linked list.
The defining characteristic of classes (vs. structs) is that they're reference types, and use reference semantics (i.e. assignment of an object only copies a reference to the object).
Classes Are Reference Types
Unlike value types, reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function. Rather than a copy, a reference to the same existing instance is used instead.
Structs, on the other hand, are value types, and use value semantics (i.e. assignment of a struct copies it entirely).
Structures and Enumerations Are Value Types
A value type is a type whose value is copied when it is assigned to a variable or constant, or when it is passed to a function.
I suggest you give this a read: The Swift Programming Language (Swift 2.2)
- Classes and Structures

var declaration with type vs without

What is the difference between this
var a = ClassA()
and this
var a: ClassA = ClassA()
Why do one vs the other?
I'm not a Swift developer but I'm fairly certain that it operates in the same way as languages like C# in this regard.
In the first case, the type of the variable is inferred from the type of the expression used to initialise it. Your a variable is thus of type ClassA and can thus refer to any object that is that type or is derived from it. In the second case, you are specifying that the variable is type ClassA explicitly rather than allowing it to be inferred.
In that second case, the annotation is redundant because the specified type is the same as that which would be inferred anyway. If those types were different though, then it would be worthwhile, e.g.
var a: BaseType = DerivedType()
In this case, the variable is being initialised with an object that is one type but the variable is specified to be a type that is more general.
If you are declaring a variable without initialising it then you need an annotation too, because there is no initialising expression from which to infer the variable's type.

For an object in scala to be immutable what is required?

Is the answer to this :
Instantiation of the object uses 'val' instead of 'var'.
Each member variable of the object being created is also 'val' instead of 'var'. This is to prevent users updating an object value after its set.
An object is immutable if there is no way for the user of that object to mutate it. This means that it must have no public methods that reassign any of its member variables or mutate any objects referred to by those variables. If all the object's members are vals this ensures the former (i.e. they can't be reassigned), but not the latter (i.e. if the objects referred to by those variables are themselves mutable, they can still be mutated by calling mutating methods on them even if they're referred to only by vals).
Also note that even if the members are declared as vars, the object can still be immutable if none of the object's methods actually reassign the variables (or call mutating methods on them) - assuming of course, they're private.
So having only val members is neither necessary nor sufficient for an object being immutable. Whether the object is referred to by a val or a var (or both) makes no difference in that matter.
#sepp2k nicely and correctly explains the criteria for an object being technically immutable. One subtle point missing from his answer is that not all member variables correspond to externally visible state. A member may also be e.g. a cached internal value to store some local, hard to compute data which is not directly visible from outside (thus qualified as private[this] in Scala). An object can have such a var member e.g. to store a computed hash value. It can even be accessible via a public getter - as long as the behaviour of the accessor is purely functional, i.e. it always produces the same value for each invocation on the same object (except that it returns faster when reusing the internally cached value).
The Scala compiler is aware of this distinction so it can help one to implement an immutable class correctly, even when using mutable state internally. This is important when generic type variance comes into play. Namely, the compiler allows a generic type parameter to be covariant even if the class contains reassignable fields of this type - as long as these fields are private[this], ensuring that one cannot have a reference to a containing object that has a statically weaker type than the type the object was defined with (which would be a precondition for variance to cause type errors).
This is explained in more detail, with a code example, in section 19.7 of Programming in Scala.