How costly is casting in Kotlin? - casting

In Kotlin, how costly is the casting of classes?
So for instance, let's have the following Test class
open class Test {
open fun question() = "Basic question"
}
and 3 inheriting classes
class MathTest : Test() {
override fun question() = "2+2=?"
}
class EnglishTest : Test() {
override fun question() = "Who created SO?"
}
class HistoryTest: Test() {
override fun question() = "When was SO created?"
}
How costly would it be to cast (for instance, let's say) 100 Test objects to either one of these 3, at runtime, in Android (and in general) ?

I messed around a little bit with disassembling the generated bytecode, and except for one case, casting is identical to Java. The one case where it seems to be different is when using the safe cast operator, as?, like so:
val thing = "" as? Int
This generates equivalent bytecode to this Java code:
String _temp = "";
if (!(_temp instanceof Integer)) {
_temp = null;
}
Integer thing = (Integer) _temp;
This makes it slightly more expensive than a regular cast in Java. However, there is no direct equivalent to this behavior in Java, short of writing a similar if statement anyways, so I think it's safe to say that casting in Kotlin is no more expensive than casting in Java.

Related

What makes safe call (question mark) to be interpreted differently from classic if?

In Kotlin, if we declare a class member as var and nullable type, compiler doesn't allow us to run the member function although we put an if statement before calling the function because the compiler can't guarantee that the member isn't been set to null after checking against null and before calling the method.
But if we are using a safe call compiler approves our code.
My question, how the compiler makes the safe call atomic? Isn't a second thread can change the variable between checking for null and calling the method (eat method in the example)?
Code for first situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
Code for second situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
The compiler puts the contents of the field to the local variable and then compares it with null. You can clearly see it if you decompile Kotlin bytecode.

Swift: RxSwift's asObservable() method and type erasure

I am having problem understanding the rationale and purpose for asObservable method in RxSwift's Observable class.
/// A type-erased `ObservableType`.
///
/// It represents a push style sequence.
public class Observable<Element> : ObservableType {
/// Type of elements in sequence.
public typealias E = Element
public func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
abstractMethod()
}
public func asObservable() -> Observable<E> {
return self
}
}
What's the purpose of asObservable when it's returning self?
Surely if you can run this method, you already have access to the object. Also, what does the "type-erased ObservableType" in the comment means?
I believe the answer is apparent if you look at the ObservableType protocol and what objects conform to it (namely things like subjects, etc.).
The only guarantee is that the object will return an Observable in response to a call to asObservable. While conformance is trivial for an Observable, it may be less so for subjects and other units. But this guarantee allows you to use all type that can provide an Observable together in the same operator chain.
In essence this is similar to Strings conformance to CustomStringConvertible.
You asked two questions:
1. What's the purpose of asObservable when it's returning self?
You almost don't need to ever use asObservable(). The only time I think you'd need is when you're assigning casting a Subject/Relay to an Observable.
Suppose you have a variable that is a BehaviorRelay. It can both, observe and be an observable.
ViewModel.swift
let deviceOrientation = BehaviorRelay<UIInterfaceOrientation>(value: UIApplication.shared.statusBarOrientation)
And then you have a variable that is not both but only an observable like below.
ViewController.swift
lazy var incorrect : Observable<UIInterfaceOrientation> = {
return self.viewModel.deviceOrientation // ERROR
}()
lazy var correct : Observable<UIInterfaceOrientation> = {
return self.viewModel.deviceOrientation.asObservable()
}()
Then you'd need to cast so you'd have the correct type.
The incorrect variable would give the following error:
Cannot convert value of type BehaviorRelay<UIInterfaceOrientation>
to closure result type Observable<UIInterfaceOrientation>
2. What does the "type-erased ObservableType" in the comment means?
I suspect Scott's comment is semi-correct. I mean for sure it's confusing. You can flatten the type of a BehvaiorRelay, PublishSubject to a Observable and then assign one Observable to another. Otherwise still they all require the associatedType to be given ie no type erasure happening.
let x : AnyHashable = 10
let y : AnyHashable = "Alex"
if x == y { print("equal" } // compiles!
var i = PublishSubject<Int>().asObservable()
var s = PublishSubject<String>().asObservable()
if i == s { print("equal" } // does NOT compile. Gives following error:
Binary operator == cannot be applied to operands of type
Observable<Int> and Observable<String>

How to override KeyValuePair<TKey, TValue> in C#?

I want to override the default structure of KeyValuePair in C#, so that I can make a KeyValuePair to accept a 'var' types.
Something like this :
List<KeyValuePair<string, var>> kvpList = new List<KeyValuePair<string, var>>()
{
new KeyValuePair<string, var>("Key1", 000),
new KeyValuePair<string, var>("Key2", "value2"),
new KeyValuePair<string, var>("Key3", 25.45),
};
Even if its possible for dictionary, then also it will solve my problem.
You could use object as your type, and then cast to/from object to desired outcomes. However, it's important to note that this is very much the opposite of object oriented programming, and generally indicates an error in your design and architecture.
Hmm I am wondering if this might help you: To have a list as you want, it is really possible BUT the "var" type (as you named it) must be the same for all KeyValuePair instances. For having whatever type you must use object or dynamic (use Haney's answer).
So considering that you want a single type for all KeyValuePair instances, here is a solution:
Firstly, create this helper class:
public static class KeyValuePairExtentions
{
public static List<KeyValuePair<string, T>> GetNewListOfType<T>(Expression<Func<T>> type)
{
return new List<KeyValuePair<string, T>>();
}
public static void AddNewKeyValuePair<T>(this List<KeyValuePair<string, T>> #this, string key, T element)
{
#this.Add(new KeyValuePair<string, T>(key, element));
}
}
To consume these functions, here is an example:
var lst = KeyValuePairExtentions.GetNewListOfType(() => new {Id = default (int), Name = default (string)});
lst.AddNewKeyValuePair("test1", new {Id = 3, Name = "Keith"});
The ideea is to rely on the powerfull type inference feature that we have in C#.
Some notes:
1) if T is anonymous and you create a new instance of a list in an assembly and consume it in another assembly it is VERY possible that this will NOT work due to the fact that an anonymous type is compiled per assembly (in other words, if you have a variable var x = new { X = 3 } in an assembly and in another var y = new { X = 3 } then x.GetType () != y.GeTType () but in the same assembly types are the same.)
2) If you are wondering whether an instance it's created or not by calling GetNewListOfType, the answer is NO because it is an expression tree function and the function is not even compiled. Even with a Func will work because I am not calling the function in my code. I am using the function just for type inference.

Why aren't type parameters allowed in Scala auxiliary constructors?

Say I'm defining a simple 2D point class in Scala, and I want to be able to construct it with various types:
class Point(x:Float, y:Float) {
this(x:Double, y:Double) = this(x.toFloat, y.toFloat)
this(x:Int, y:Int) = this(x.toFloat, y.toFloat)
// etc...
}
I want to boil this down using a template, such as:
class Point(x:Float, y:Float) {
this[T](x:T, y:T) = this(x.toFloat, y.toFloat)
}
I know this won't work anyway, since T could be a type for which toFloat isn't defined, but the compiler error I get is:
no type parameters allowed here
Is this just unsupported in Scala? If so, why, and is there any simple way to get around this?
Scala's class constructors (unlike Java's) can't take type parameters, only the class itself can. As to why Scala made this design choice, I assume the main reason is simplicity.
If you want a secondary "builder" method that is generic, the natural thing to do is define it on the companion object. For example,
object Point {
def build[T : Numeric](x: T, y: T) = {
val n = implicitly[Numeric[T]]
new Point(n.toFloat(x), n.toFloat(y))
}
}
class Point(val x:Float, val y:Float)
val p = Point.build(1, 2) // Companion object's builder
p.x + p.y
Here I've used the Numeric typeclass to get a generic toFloat method.
I played with this for awhile, getting as "close" as...
class Point(x:Float, y:Float) {
def this[T <: Any { def toFloat: Float }](x:T, y:T) = this(x.toFloat, y.toFloat)
}
...which results in "error: no type parameters allowed here" (just as per the post) and then I realized...
If the initializer could take type parameters it would be ambiguous with the class parameters, if any. Not that this couldn't be worked about in the language specification... but it is a more complex case at the very least. There might also be Java interoperability issues.
Imagine:
class Foo[T](x: T) {
def this[X](z: X) = ...
}
new Foo[Int](42) // T is Int? X is ...? Or ...?
Personally I wish Scala followed an Eiffel-like pattern (only named constructors or "factory methods"), but alas, that would not be Scala.
Happy coding.

What type should my variable be declared as?

I am new to C# / OOP and am working on converting an existing application into .net 4.0 framework.
My code is as follows:
Class abc
private IList<string[]> GetReportBatchList()
{
List<string[]> rowList = new List<string[]>();
SqlParameter[] prm = { new SqlParameter("#rpt_doc_type_id", SqlDbType.Int, 9) };
prm[0].Value = 101;
try
{
.....
.....
.....
}
return rowList;
}
class xyz
using abc;
Private Function GenerateReport()
Try
{
Dim rptBatchList As ??????
rptBatchList = GetReportBatchList()
While rptBatchList.Read()
......
......
......
}
catch
{
......
}
What type should rptBatchList be declared as?
Since the return value of GetReportBatchList() has IList of string as its type, it makes sense that rptBatchList should be the same type.
Your second example is VB, but you say you are using C#, so...
For C# it would be IList<string[]>.
My VB is a little rusty, but I think it would be IList(Of String()).
Hmmm... is this a question about correct return types, or a question about translating C# into VB.Net?
According to the function definition you have, rptBatchList will be of type IList<string[]> - obviously declared in the correct syntax for VB.Net.
Further to that, because it is a list of string arrays, it doesn't have a Read() function, so maybe you were looking for something that derives from DbDataReader instead (like a SqlDataReader)? If you do intend to stick with the current definition then you can use either a foreach or a for loop to iterate over the list elements, or you can use Linq extensions and use something like this:
rptBatchList.ForEach(z => { z.ForEach(x => doSomethingWithThisResultString(x)); } );
although that can get messy fast - you probably want to just stick with a couple of nested foreach loops.