Read Static Property from Object

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



Leave a reply



Submit