Object initializers in C++/CLI - c++-cli

In C# I can do this:
foo( new SomeClass() { SomeProperty = "value" } );
Now in C++/CLI I can equivalently do this:
auto tmp = gcnew SomeClass();
tmp->SomeProperty="value";
foo (tmp);
But is there a syntax for C++/CLI that is similar to C# object initializers? In particular I don't want to define a temporary variable and I can't add arguments to the constructor itself.

Related

Class field with different argument types (setter overloading)

I have a class with a field of type long and I would like to pass either an Int or a Long value.
So I thought I can make a second setter with the same name, but different argument.
Kotlin does not complain and I can even call both setters from Java (same name, one automatically created with long from Kotlin). In Java I just call setMyNumber(long or int) value and the compiler will assign the correct method.
But why can't I do myNumber = 4 in Kotlin, why does it not call the other setter?
Is there a different way I can achieve this functionality, but still keep the property notation (yes I know I can write to setter methods, but then I have to call them with a method call rather just assigning a value)?
class MyClass {
var myNumber: Long = 0L // internal setMyNumber(value: Long)
fun setMyNumber(newNumber: Int) {
myNumber = newNumber.toLong()
}
}
As of writing, what you're trying to do is not supported. (See: Allow setters overloading for properties)
A workaround would be using the Superclass for all platform classes representing numeric values:
class MyClass {
var myNumber: Number = 0L
set (value) { field = value.toLong() }
}
val myClass = MyClass()
val anInt: Int = 1
val aLong: Long = 1L
myClass.myNumber = anInt
myClass.myNumber = aLong
Try it online!

Exposing an object variable as public makes its members unresolvable

I have a Kotlin class with a member object:
private var strings = object { var foo = ""; var bar = "" }
Inside my class's functions, I can reference strings.foo and strings.bar.
But when I make strings a public var, suddenly all of its members become "unresolved references". Why?
class Foo {
// Making this `private` fixes the errors below for some reason
public var strings = object {
var foo = ""
var bar = ""
}
fun initialize() {
strings.foo = getFoo() // "Unresolved reference: foo"
strings.bar = getBar() // "Unresolved reference: bar"
}
}
(What I'm trying to do here is expose a whole bunch of string resources as constants so I don't have to use the literal string values throughout my code. I'm actually using lateinit var for each member but that doesn't change the result here.)
strings is defined with an object literal. You probably want to use an regular object declaration instead:
object Strings {...}
strings = Strings()
With the object literal, strings is an anonymous object whose type is "usable (and visible) only in the scope where it is declared".
without any explicitly declared supertype, menaing Any is implicit super type of this object.
When you make strings a public var, it escapes the current scope and is implicitly downcasted to its supertype; without any explicitly declared supertype, the supertype is Any, so of course you get errors trying to reference the properties foo and bar.
From Kotlin spec
The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.
When a value of an anonymous object type escapes current scope:
If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.
Note: an implicit cast may arise, for example, from the results of type inference.
Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global- or classifier-scope property, as those are parts of an externally accessible interface.
You could also use a Companion object:
companion object Strings {
var foo = ""
var bar = ""
}
fun init(){
foo = getFoo()
bar = getBar()
}

With Kotlin delegate, have reference of the parent "this" object when creating the delegate object

I would like to use Delegation on my Kotlin project, but I have a peculiar requirement. The delegation object itself should hold a reference to the parent object. To give you an example let's consider the following code:
interface MyInterface
class MyImpl(val a: MyTest?) : MyInterface
class MyTest : MyInterface by MyImpl(null)
What I'd like to do is replace null above with a this reference to MyTest object. But compiler doesn't let me with the error
'this' is not defined in this context
When I decompile the produced code, I get something like
public final class MyTest implements MyInterface
{
private final /* synthetic */ MyImpl $$delegate_0;
public MyTest() {
this.$$delegate_0 = new MyImpl(null);
}
}
which would seem perfectly legal, if I wanted to pass this instead of null when the delegate is initialized. But I can't figure how to do it. Is it a Kotlin's restriction or am I doing something wrong?
I know that I can bypass this restriction by using a var inside MyImpl and give a reference to parent.this at later time on my code. But this would mean that MyImpl will have a mutable reference of something that could be val instead, and I don't think this solution is elegant enough.

Is it possible to create and use custom System::String^ extension methods in C++/CLI?

I tried making an extension to the built-in String class using C++/CLI, and using it from C++/CLI without success.
Here's the simplest I can boil it down to:
[System::Runtime::CompilerServices::Extension]
public ref class MyStringExtensions abstract sealed {
public:
[System::Runtime::CompilerServices::Extension]
static bool TestMethod(System::String^ str) { return false; }
};
Now, when I try to use this in other C++/CLI code, I get a compiler message indicating that TestMethod is not a method of String.
String^ foo = gcnew ...
...
blah = foo->TestMethod(); // compile-error
Any ideas?
C++ doesn't have extension methods.
But it does have ADL (Argument-dependent lookup, also known as Koenig lookup) which is arguably even nicer.

Is there any difference between declaring a variable with 'def' and declaring it with a known type?

Assuming I have a defined class
class MyClass {
}
Is there a hit in performance in runtime in doing def c = new MyClass() instead of MyClass c = new MyClass()? Or is it exactly the same?
def is a replacement for a type name. In variable definitions it is used to indicate that you don't care about the type.
If you don't declare the type of variable, Groovy under the covers will be declared as type Object. You can think of def as an alias of Object.
In your example:
def c = new MyClass()
// transform to:
java.lang.Object c = new MyClass()
MyClass c = new MyClass()
// transform to:
MyClass c = new MyClass()