<?
require_once('Type.php');
//I want to start with severalimportant notes!
//You cannot create a generic interface!!!
//You cannot extend a generic class!!! (You can but it might not work as expected!)
//If you need to extend a generic class mail me and I'll think about it.
//Lets start with the Type class
//There are two ways to get an instance of that class
//1. From string
//There are several primitive data types: `int`, `double`, `number`, `bool`, `array`, `string`, `object`, `resource`
$a = Type::GetType('`int`');
//For a class use the class' name
$a = Type::GetType('Type');
//Lets assume we have a class A that is generic. You can pass it to another generic class like this:
$a = Type::GetType('A<`string`>');
//Some examples:
$a = Type::GetType('GenericDictionary<`int`,GenericCollection<`string`>>');
$a = Type::GetType('GenericDictionary<`int`,GenericDictionary<`int`,`string`>>');
//If there is some error in the given string, an exception will be thrown unless you set the second argument of the Type::GetType to false
$a = Type::GetType('My_strange-Type`1'); //throw an exception
$a = Type::GetType('My_strange-Type`1', false); //returns null
//2. From variable
//You should be able to get a Type object from any variable
$b = Type::TypeOf($a);
//An instance of the Type class as many methods
$c = $b->IsGeneric(); //Returns bool value: true if the Type is genric, false otherwise.
$c = $b->IsInterface(); //Returns bool value: true if the Type is an interface, false otherwise.
$c = $b->IsClass(); //Returns bool value: true if the Type is a class, false otherwise.
$c = $b->IsPrimitive(); //Returns bool value: true if the Type is primitive, false otherwise.
$c = $b->IsAbstract(); //Returns bool value: true if the Type is abstract, false otherwise.
$c = $b->IsFinal(); //Returns bool value: true if the Type is final, false otherwise.
$c = $b->IsSubclassOf($a); //Returns bool value: true if the Type $b is subclass of the type $a, false otherwise.
//Note: this returns false if $a is generic!
$c = $b->ImplementsInterface('IEquatable'); //Returns bool value: true if the Type $b implements the interface 'IEquatable', false otherwise.
$a = Type::GetType('GenericDictionary<`int`,GenericDictionary<`int`,`string`>>');
$c = $a->Name(); //Returns the name of the type: GenericDictionary in this case
$c = $a->FullName(); //Returns the full name of the type: GenericDictionary<`int`,GenericDictionary<`int`,`string`>> in this case
$c = $a->GetGenericTypesCount(); //Returns the number of generic types that this Type has: 2 in this case
$c = $a->GetGenericTypes(); //Returns an array of Type objects. In this case `int` and GenericDictionary<`int`,`string`>
$c = $a->IsItemFromType($b); //Returns true if the item $b is from the type $a, false otherwise
//That's all about the Type class
//Now lets continue with the IGeneric interface
//To make a generic class, you must implement this interface.
class MyClass implements IGeneric {
private $a;
//I think the best place to get the generic types is in the constructor and that's what I'm doing
public function __construct(Type $a) {
$this->a = $a;
}
//This method returns an array of all Type arguments this class uses
public function GetTypes() {
return array($this->a);
}
//Returns the number of the needed Type arguments by this class
public static function NumberOfTypes() {
return 1;
}
//That's a test function
public function MyF1($item) {
//Now if I need this $item to be from some of the generic types I just use:
if ($this->a->IsItemFromType($item)) {
//do what I need to do..
}
//throw an exception or something
}
}
$m = new MyClass(Type::GetType(`int`));
//This seems to be all. If you need any help - mail me.
?>
|