Read static property from object
You've hit an obscure and very interesting bug in Swift 1.2. Swift has a long history of bugs related to static variables required by protocols, and this appears to be another one.
The problem here, apparently, is that you have tried to mix and match protocol-based characteristics with class-based characteristics. Suppose you had said this:
var currentTheme = DefaultTheme()
Then currentTheme
would be typed as a DefaultTheme - an instance of a class. This means you can access a class member from the instance by passing thru the dynamicType
of that instance:
println(currentTheme.dynamicType.name) // "Default theme"
But you can't do that in your code, because you have typed currentTheme
as a Theme - a protocol:
var currentTheme : Theme = DefaultTheme()
This does weird things to the notion of the name
property, which is imposed by the protocol, and so you can't access the name
property at all.
You would not have this problem if Theme were DefaultTheme's superclass. In that case, you could use a class property (which would have to be a computed property) and it would work polymorphically. In Swift 1.2, that might be your best bet:
class Theme {
class var name : String { return "Theme" }
}
class DefaultTheme: Theme {
override class var name : String { return "Default theme" }
}
var currentTheme : Theme = DefaultTheme()
println(currentTheme.dynamicType.name) // "Default theme"
On the other hand, when you upgrade to Swift 2, you will find that the bug is fixed, and so print(currentTheme.dynamicType.name)
works perfectly even with a protocol:
protocol Theme {
static var name : String { get }
}
class DefaultTheme: Theme {
static var name = "Default theme"
}
var currentTheme : Theme = DefaultTheme()
print(currentTheme.dynamicType.name) // "Default theme"
Retrieve Static Property Value From Class Name
Solution (with your help):
var qualifiedName = "MyObjects.MyClass, MyObjects";
var theType = Type.GetType(qualifiedName);
var importantVar = theType.GetProperty("MyStaticProperty").GetValue(null);
Able to access static properties through the object using the arrow operator -?
The problem is due to the misunderstanding of what a property is, a property is a variable defined in a class. If you expand your example above and add a property...
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
class Foo {
public static $a = "static property";
public static function aStaticMethod() {
// ...
echo 'In Static method';
}
}
Foo::aStaticMethod();//output: In Static method
echo Foo::$a;
$obj = new Foo;
$obj->aStaticMethod();//output: In Static method
echo $obj->a;
This tries to reference $a
, but the output is...
In Static methodstatic propertyIn Static methodPHP Notice: Accessing static property Foo::$a as non static in /home/nigel/workspace2/Test/t2.php on line 18
PHP Stack trace:
PHP 1. {main}() /home/nigel/workspace2/Test/t2.php:0
PHP Notice: Undefined property: Foo::$a in /home/nigel/workspace2/Test/t2.php on line 18
PHP Stack trace:
PHP 1. {main}() /home/nigel/workspace2/Test/t2.php:0
Notice: Accessing static property Foo::$a as non-static in /home/nigel/workspace2/Test/t2.php on line 18
Call Stack:
0.0001 348024 1. {main}() /home/nigel/workspace2/Test/t2.php:0
Notice: Undefined property: Foo::$a in /home/nigel/workspace2/Test/t2.php on line 18
Call Stack:
0.0001 348024 1. {main}() /home/nigel/workspace2/Test/t2.php:0
(Note that I've set it to report all errors/warnings etc.)
How do we access static properties in a class since the latter is not an object?
Statics are statics. In this scenario, the class acts more like a namespace. It's not that the statics exist on the class, but rather simply accessed through the class.
Access Static properties using PHP object
Static properties may be accessed on various ways.
Class::$aStaticProp; //by class name
$classname::$aStaticProp; // As of PHP 5.3.0 by object instance
Static properties cannot be accessed through the object using the arrow operator ->
.
As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static).
More you can read in manual
How to get a Static property with Reflection
Ok so the key for me was to use the .FlattenHierarchy BindingFlag. I don't really know why I just added it on a hunch and it started working. So the final solution that allows me to get Public Instance or Static Properties is:
obj.GetType.GetProperty(propName, Reflection.BindingFlags.Public _
Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or _
Reflection.BindingFlags.FlattenHierarchy)
Best way to access Class property inside a Static method with PHP
You need the $
sign in front of the variable/property name, so it becomes:
self::$my_paths['imagemagick']
And my_paths
is not declared as static. So you need it to be
private static $my_paths = array(...);
When it does not have the static
keyword in front of it, it expects to be instantiated in an object.
Access static property from variable referenced to a class
alias
is a static field so it does not exist on type AbsClass
since it is a type of an object produced by the class constructor.
Changing AbsClass
to typeof AbsClass
removes the error:
class Derived extends AbsClass {
protected static alias = "drv";
getAlias(obj?: typeof AbsClass) { // <- Type changed here
const accessClass = (obj?.constructor ?? this.constructor) as typeof AbsClass; // <- and here
return accessClass.alias;
}
}
Playground with full example
Link to the documentation where the difference between the static and instance sides of classes is described in details.
Related Topics
Convert String to Staticstring
Changing Tab Bar Color (Swift)
Xcode 7 Run on MAC Osx 10.10 Yosemite
Bringing iOS Frameworks Through Carthage in Xcode 12.0
Convert Optional String to Int in Swift
How to Insert a Sublayer in Swift
How to Restrict an Enum to Certain Cases of Another Enum
Core Image Filter Cisourceovercompositing Not Appearing as Expected with Alpha Overlay
How to Split a String into a [String] and Not [Substring]
Unwrapping Optional in Swiftui View
Passing Property Type as Parameter
Avaudiosinknode with Non-Default, But Still Device-Native Sample Rates
iOS 10 Notification Content Extension Not Loading
How to Call a Selector-Based Timer Method on a Swift Struct