Managed C++ ref class - managed-c++

Any good site or explanation on what is a ref class and when to declare a class to be a "ref class"?
The explanation on msdn wasn't enough for me,
base_type(optional)
A base type. A ref class or ref struct can inherit from zero or more managed interfaces and zero or one ref types. A value class or value struct can only inherit from zero or more managed interfaces.
ref
The ref keyword tells the compiler that the class or structure will be allocated on the heap and a reference to it will be passed to functions or stored in class members. The value keyword tells the compiler that all of the data in the class or structure is passed to functions or stored in members.

Basically, a ref class is a CLR class. It's the equivalent of class in C#.
This creates a reference type managed by the CLR. If you want to make a class that's usable from C#, you'd normally create a ref class. (ref struct, by the way, does exactly the same thing, but with C++'s standard class vs. struct default accessibility rules.)
Also, just for reference - in order to make a value type (struct in C#), you'd use value class or value struct.
A good explanation of many of these new keywords is Herb Sutter's post on C++/CLI Keywords. This is a useful reference if you're new to C++/CLI, but have a solid C++ background.

Related

Implementing C# interfaces with nullable reference types in F#

I'm trying to learn F# by converting an existing .NET Core solution in C# over, one project at a time. I currently have an interface in C# with nullable reference types:
public interface IVehicle {
public int GetWheels();
public string? GetLicensePlate();
}
And this interface is implemented in a number of other projects which depend on this one. I'm trying to convert one of these over, but if I try
type Car(serialNumber: string) =
interface MyProjectInterfaces.IVehicle with
member this.GetWheels() = 4
member this.GetLicensePlate() =
match LicensePlateService.GetLicencePlate(serialNumber) with
| Some(x) -> System.Nullable(x)
| None -> System.Nullable()
I get the error:
This expression was expected to have type 'string' but here has type 'Nullable<string>'
This doesn't seem to affect value types, so I'm assuming it's something to do with string being a reference type.
What do I do to solve this? Presumably I could rewrite the underlying interface to use F# and thus options, but there are other C# projects that implement the interface and I don't want to have to rewrite the whole solution in one go. Or am I doing F# completely wrong?
This is a confusion between C# 8's nullable references and nullable value types, aka Nullable<T>. If you look at the definition of Nullable<T>, you'll find:
public struct Nullable<T> where T : struct
which means it's only for value types. int? is short for Nullable<int>.
That's different from nullable references.
The nullability modifier for reference types doesn’t introduce a new type. Reference types are still nullable and compiling string? results in IL that’s still just System.String.
The difference at the IL level is the decoration of nullable modified types with a NullableAttribute.
In other words, it's just a compiler construct - one which isn't visible to F#.
match LicensePlateService.GetLicencePlate(serialNumber) with
| Some(x) -> x
| None -> null
will be the correct, albeit non-idiomatic replacement.

How to safely cast a reflected class in Kotlin

I need to dynamically load classes at runtime in Kotlin. I would like to check that they implement my interface, and if so, all green. Unfortunately, Kotlin's "smart casts" is failing me:
var className = "some.class.Name"
val unsafeClass = Class.forName(className).kotlin
require(unsafeClass.isSubclassOf(MyInterface::class)) {
"Class '$className' is not a MyInterface"
}
val safeClass = unsafeClass as KClass<MyInterface>
^^^^^^^^^^^^^^^^^^^^^^
Unchecked cast: KClass<out Any!> to KClass<MyInterface>
I'm clearly checking that the class implements the given interface. Can I re-phrase this code to avoid the warning?
I tried to test with is KClass<MyInterface> but I get a type erasure error (obviously, because the generic type information disappears at runtime.)
Edit: to clarify, my application needs to read class names "some.class.Name" at startup, during configuration; load those classes; check that they satisfy an interface; and store a Class or KClass reference for later. During runtime, it will use those references to create objects, using cls.createInstance() or such.
My question: is there any way to do so without getting unsafe cast warnings?
I can either get a warning at configuration time, when I cast the KClass<*> to KClass<MyInterface> (even though I required the class to be a subclass) but then I get no warning later on, because .createInstance() on a KClass<MyInterface> class reference returns a type-checked MyInterface instance.
Or, I can store the references as KClass<*>, without warnings at configuration time, but then I'll get the warning in the place where I create the instances, because I'll need to unsafe cast Object instances to MyInterface.
Is there any solution that will satisfy the compiler?
JVM and Kotlin implement generics only at the compiler level. One cannot see generic parameters of a generic class at runtime.
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
At runtime, there is no difference between Class<*> and Class<MyInterface>. These two are the same instance of Class type.
The warning that you have means that you have no information in the generic parameter at runtime, a compiler cannot validate it too, and it only can trust you
I do not see the reason cast the KClass to the KClass<MyInterface>. It is only necessary for an object, not it's class. Also, it probably can be simplified to use Class<*> instead, e.g:
val className = "some.class.Name"
val unsafeClass = Class.forName(className)
require(MyInterface::class.java.isAssignableFrom(unsafeClass)) {
"Class '$className' is not a MyInterface"
}
val safe = unsafeClass.newInstance() as MyInterface
This cast is not only unchecked, it's actually incorrect: because AMyInterfaceImpl::class has type KClass<AMyInterfaceImpl> and KClass is not covariant (for good reason), it does not have the type KClass<MyInterface>. You can see that from this code not compiling:
class AMyInterfaceImpl : MyInterface { ... }
val cls: KClass<MyInterface> = AMyInterfaceImpl::class
So if the cast could be checked, it would fail.
KClass<out MyInterface> would be correct, but I don't think the compiler will understand this and allow smart cast. It's just too rarely useful to teach the compiler.

Determine whether an instance is an instance of a data class

Given the following classes
abstract class SomeAbstractClass { abstract val name: String }
data class DataClass( override val name: String ) : SomeAbstractClass()
class NoDataClass( override val name: String ) : SomeAbstractClass()
For any instance of SomeAbstractClass, can I determine whether it is a data class without relying on type checking?
Some background: this seemed the best way of combining inheritance and data classes to me, as suggested in a different answer. Now, within the initializer block of SomeAbstractClass, I want to throw an exception in case the derived type is not a data class to ensure 'correct' (immutable) implementations of derived types.
Using reflection, the Kotlin class description (KClass) can be obtained using the ::class syntax on the instance you want to investigate (in your case, this::class in the initializer block of the abstract class). This gives you access to isData:
true if this class is a data class.
However, as Oliver points out, data classes can still contain var members, so you likely also want to check whether all member variables (and their member variables recursively) are defined as val to ensure immutability of all deriving classes.

How to get a KClass of Array?

I wrote the below code to get a KClass of Array<*>.
Array::class
However, this code has a compilation error.
Kotlin: Array class literal requires a type argument, please specify one in angle brackets
Do you know the reason or solution?
On the JVM platform, Kotlin Array<T> types are mapped to Java arrays, which, unlike Java generic types, are not subject to type erasure, they are reified instead.
It means, among other things, that arrays with different element types are represented by different classes, which have different Class<T> tokens, and these class tokens contain the information about the element type as well. There's no generic array type, but only array types for arrays with different element types.
Since generic Array<T> doesn't exist, you cannot use its reflection either, you can only get the runtime type information of array types with specified element types:
val c = Array<Int>::class // corresponds to Java Integer[] type
val d = Array<Array<String>>::class // corresponds to Java String[][]
val e = IntArray::class // corresponds to Java int[]
If you need to check whether an arbitrary class is an array type, you can do it with Java reflection:
val c = Array<Int>::class
println(c.java.isArray) // true

Fortran Derived Type - Public Pointer to a Private Array

I'm trying to define a Fortran derived type that has a private allocatable array. However, I would like to be able to access the array via a public pointer for use in other modules. E.g.
type,public :: test
private
real,allocatable :: a(:,:,:)
contains
real,pointer,dimension(:,:,:),public :: point => a
end type test
I just get a compiler error when attempting it like the above.
Is this possible without writing a subroutine that does the pointing for me?
No.
The syntax error is perhaps because you have the pointer component in the type bound procedure part of the type definition (after the contains), not in the component part (before the contains).
Beyond syntax, there are some problems with what you want to do:
You cannot associate a pointer with a component of a type definition. Pointers can be associated with components of objects (a subobject). Similarly, you cannot associate a pointer with something that doesn't have the target attribute. Types and components of types can't have the target attribute. Variables of that type, or objects pointed at by pointer components of an object may have the target attribute.
You cannot associate a pointer with something that isn't allocated. If something isn't allocated then there isn't anything to point at.
An initializer for a pointer component cannot refer to something that is allocatable. In addition to the target attribute the thing that it refers to must have the SAVE attribute. As the case with the TARGET attribute, variables have the save attribute, not type or component definitions.
Associating a pointer with a component of an object may defeat the point of making the component private in the first place. This leads to the question - what are you trying to do?

Resources