I have a protocol A which has a static variabe x. B is a implementation of A. In Class C I pass an instance of B and assigned it to a. How can I access 2 (value of x in class B) from it ?
protocol A {
static var x : Int { get }
}
class B : A {
static var x: Int {
return 2
}
}
class C {
// instance of B is assigned to a.
let a: A
print(a.x)
}
A static variable belongs to the class, not the instance. You can refer to the class by calling dynamicType:
print(a.dynamicType.x)
So things have changed a little bit since this answer was posted
type(of: a).x
Within class C a is a property that holds an instance of a type adhering to protocol A. A static variable (otherwise known as a class variable) however is not accessible from an instance, it is accessible from the class, so you will access the value in the following way:
B.x
An instance variable would be a different matter and the code for this would be:
protocol A {
var x : Int { get }
}
class B : A {
var x: Int {
return 2
}
}
class C {
// instance of B is assigned to a.
let a: A
init() {
a = B()
}
}
C().a.x
These can happily co-exist with the same variable names:
protocol A {
static var x : Int { get }
var x : Int { get }
}
class B : A {
static var x: Int {
return 2
}
var x: Int {
return 2
}
}
class C {
// instance of B is assigned to a.
let a: A
init() {
a = B()
}
}
C().a.x
B.x
Related
I have a class A and it extends B and mixes in C like the code below. How do I make it work?
class A extends B with C {
#override
int getValue() {
// Call's C's getValue.
super.getValue();
// Now I want to call B's getValue. How do I do that?
return B.getValue(); // Doesn't work.
}
}
class B {
int getValue() {
return 1;
}
}
class C {
int getValue() {
return 2;
}
}
How can I execute B's getValue? Thanks.
The mixin method from C shadows the method from B, so you can't use super directly to refer to the B method. You need to introduce a way to access it.
What you can do is to put a private redirecting function in between the B class and the C mixin application:
class A extends B with _Helper, C {
int getValue() {
// It's C
super.getValue();
// Now I want to get B's getValue how do it?
return super._getValueFromB();
}
}
class B {
int getValue() {
return 1;
}
}
mixin C {
int getValue() {
return 2;
}
}
mixin _Helper on B {
int _getValueFromB() => super.getValue();
}
Since the mixin application order is B, B-with-_Helper, B-with-_Helper-with-C, the super of the B-with-_Helper superclass is B, and the _getValueFromB will access it correctly.
Given a kodein instance:
interface SharedInterface {}
class A : SharedInterface
class B : SharedInterface
class C : SharedInterface
class D
fun main(args: Array<String>) {
val kodein = Kodein {
bind<A>() with singleton { A() }
bind<B>() with singleton { B() }
bind<C>() with singleton { C() }
bind<D>() with singleton { D() }
}
}
Is there a way to get instances of A, B, C but not D from kodein?
The closest I got was:
val singletonBindings = kodein.container.bindings.filterValues { it is SingletonBinding<*> }
val singletonInstances = singletonBindings.map { it.value.getInstance(???, ???, Unit) }
Set binding was of little help as I was not able to bind single instance as set-enabled-type and the type I want it to be bound as:
interface SharedInterface {}
class A : SharedInterface
class B : SharedInterface
class C : SharedInterface
class D
fun main(args: Array<String>) {
val kodein = Kodein {
bind() from setBinding<SharedInterface>()
bind<A>().inSet() with singleton { A() }
bind<B>().inSet() with singleton { B() }
bind<C>().inSet() with singleton { C() }
bind<D>().inSet() with singleton { D() }
}
val shared = kodein.instance<Set<SharedInterface>>()
}
Causes Exception in thread "main" java.lang.IllegalStateException: No set binding to bind<Set<out A>>() with ? { ? }
This fixes the issue but is ugly:
val kodein = Kodein {
bind() from setBinding<SharedInterface>()
bind<SharedInterface>().inSet() with singleton { instance<A>() }
bind<SharedInterface>().inSet() with singleton { instance<B>() }
bind<SharedInterface>().inSet() with singleton { instance<C>() }
bind<A>() with singleton { A() }
bind<B>() with singleton { B() }
bind<C>() with singleton { C() }
bind<D>() with singleton { D() }
}
val shared = kodein.instance<Set<SharedInterface>>()
There is no way in Kodein 4 to do that other than what you just did.
Can you open a ticket on Kodein's GitHub ?
I may have time to squeeze that into Kodein 5 ;)
I have a an instance of A and b an instance of B
a must be able to call a method on b and b must then immediatly call a method on a if some checks pass.
To achieve this I would have cyclic DI
public A(B b) { _b = b; }
public void CallToB() { _b.Method(); }
public void Method() { DoSomething(); }
public B(A a) { _a = a; }
public void Method() { if (SomeCheck()) _a.Method(); }
I know I could get arround this, using events and let b be unaware/independant of a. But it would feel wrong.
Note: I haven't seen an answer to this question where bidirectional communication was made possible.
You can solve this issue by depending on interfaces instead of concrete types and then use property injection. Here is an example:
public interface IA
{
void Method();
}
public class A : IA
{
private readonly IB _b;
public A(IB b){_b = b;}
//...
}
public interface IB
{
void Method();
}
public class B : IB
{
private readonly IA _a;
public B(IA a){_a = a;}
//...
}
public class BCycleDependencyBreaker : IB
{
private IB _b;
public IB b
{
set { _b = value; }
}
public void Method()
{
_b.Method();
}
}
You then use BCycleDependencyBreaker when you compose like this:
var b_cycle_dependency_breaker = new BCycleDependencyBreaker();
//Make a depend on this implementation of b that currently does nothing
A a = new A(b_cycle_dependency_breaker);
//Make b depend on a
B b = new B(a);
//Now, let the proxy implementation delegate calls to the real b
b_cycle_dependency_breaker.b = b;
I have a custom collection class with an embedded array written in Obj-c. The class implements NSFastEnumerator protocol in order to be iterable in Obj-c.
For my Swift classes I had to add the following code based on apporaches on SOF.
extension CustomCollection: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
Which again makes it iterable in Swift classes.
All is good until I need to use this class as a Generic type in one of my Swift base classes.
class SomeBaseClass<T: CustomCollection> {
typealias Collection = T
var model: Collection?
// Implementation goes here
}
When I try to iterate over my 'model' property, I get Command Signal Failure Error during build.
Any idea how this needs to be done and whether it's even possible to be done?
Running XCode 7 beta 6 and Swift 2.0
Thanks.
Here is what I came up with Xcode 7.0.1:
First the CustomCollection class. I've keep it simple since I don't know what yours is doing.
public class CustomCollection: NSFastEnumeration
{
var array: NSMutableArray = []
#objc public func countByEnumeratingWithState(state: UnsafeMutablePointer<NSFastEnumerationState>, objects buffer: AutoreleasingUnsafeMutablePointer<AnyObject?>, count len: Int) -> Int {
var index = 0
if state.memory.state != 0 {
index = Int(state.memory.state)
}
if index >= self.array.count {
return 0
}
var array = Array<AnyObject?>()
while (index < self.array.count && array.count < len)
{
array.append(self.array[index++])
}
let cArray: UnsafeMutablePointer<AnyObject?> = UnsafeMutablePointer<AnyObject?>.alloc(array.count)
cArray.initializeFrom(array)
state.memory.state = UInt(index)
state.memory.itemsPtr = AutoreleasingUnsafeMutablePointer<AnyObject?>.init(cArray)
return array.count
}
}
Then there's the code you provided.
extension CustomCollection: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
class SomeBaseClass<T: CustomCollection>
{
typealias Collection = T
var model: Collection?
}
With all this, I'm able to run the following
var myModel = CustomCollection()
myModel.array.addObject("This")
myModel.array.addObject("is")
myModel.array.addObject("a")
myModel.array.addObject(["complex", "test"])
var myVar = SomeBaseClass()
myVar.model = myModel
for myObject in myVar.model!
{
print(myObject)
}
And the console prints
This
is
a
(
complex,
test
)
Hope it helps!
Problem:
Is it possible to cast dynamically to a type?
For example, could this be possible, using mirrors:
var reflectee = im.getField(simpleName).reflectee;
var converted = testVal as reflectee.runtimeType;
Context:
I want to make a Mixin class which defines a validate method:
abstract class Validatable {
bool validate(Map document) {
}
}
It will iterate over the variables defined for the class where it is mixed in, and checks if the variable in the document are of the same type.
Now, it is working with getting the runtimeType of the respective variables, but it is very restrictive as it does not cast. For example:
var a = 1.1;
var b = 1;
print(a.runtimeType == b.runtimeType); // false
It would be better to better to check with as, but I cant see how to get this to work. Becase:
a = b;
print(a.runtimeType); // int
and not double, as one might expect.
Is it possible?
You could use
import 'dart:mirrors';
class A {
}
class B extends A {
}
class C extends A {
}
void main(args) {
var a = 1.1;
var b = 1;
var x = reflect(b);
print(x.type.isSubtypeOf(reflectType(num)));
print(x.type.isAssignableTo(reflectType(num)));
print(x.type.isAssignableTo(reflectType(double)));
var myb = new B();
print(reflect(myb).type.isSubtypeOf(reflectType(A)));
print(reflect(myb).type.isAssignableTo(reflectType(A)));
print(reflect(myb).type.isAssignableTo(reflectType(C)));
}