C# не поддерживает это. Hejlsberg описал причины того, что не была реализована опция в интервью с Bruce Eckel :
И не ясно, что добавленная сложность стоит маленького урожая, который Вы получаете. Если что-то, что Вы хотите сделать, непосредственно не поддерживается в ограничительной системе, можно сделать это с шаблоном "фабрика". Вы могли иметь
Matrix
, например, и в томMatrix
требуется определить метод скалярного произведения. Это, конечно, которое означает Вас в конечном счете, должно понять, как умножиться дваT
с, но Вы не можете сказать, что как ограничение, по крайней мере, не, еслиT
int
,double
, илиfloat
. Но то, что Вы могли сделать, имеют ВашMatrix
, берут в качестве аргументаCalculator
, и в [1 111], имеют метод, названныйmultiply
. Вы идете реализация это, и Вы передаете ееMatrix
.
Однако это приводит к довольно замысловатому коду, где пользователь должен предоставить их собственное Calculator
реализация для каждого T
, что они хотят использовать. Пока он doesn’t должны быть расширяемы, т.е. если Вы просто хотите поддерживать постоянное число типов, такой как [1 116] и double
, можно сойти с рук относительно простой интерфейс:
var mat = new Matrix(w, h);
( Минимальная реализация в Сути GitHub. )
Однако, как только Вы хотите, чтобы пользователь был в состоянии предоставить их собственные, пользовательские типы, необходимо открыть эту реализацию так, чтобы пользователь мог предоставить их собственное Calculator
экземпляры. Например, для инстанцирования матрицы, которая использует пользовательскую десятичную реализацию с плавающей точкой, DFP
, you’d должны записать этот код:
var mat = new Matrix(DfpCalculator.Instance, w, h);
†¦ и реализация все участники для [1 120].
альтернатива, которая, к сожалению, совместно использует те же ограничения, должна работать с занятиями по политике, , как обсуждено в ответе Sergey Shandar’s .
Я всегда добавляю следующий метод инициализации в свою загрузку для передачи конфигурации в реестр.
protected function _initConfig()
{
$config = new Zend_Config($this->getOptions(), true);
Zend_Registry::set('config', $config);
return $config;
}
Это немного укорачивает ваш код:
class My_UserController extends Zend_Controller_Action
{
public function indexAction()
{
$manager = new My_Model_Manager(Zend_Registry::get('config')->my);
$this->view->items = $manager->getItems();
}
}
В качестве альтернативы вместо использования Zend_Registry вы также можете создать одноэлементный класс Application, который будет содержать всю информацию о приложении с общедоступными функциями-членами, которые позволят вам получить доступ к соответствующим данным. Ниже вы можете найти фрагмент с соответствующим кодом (он не будет работать как есть, просто чтобы дать вам представление о том, как его можно реализовать):
final class Application
{
/**
* @var Zend_Config
*/
private $config = null;
/**
* @var Application
*/
private static $application;
// snip
/**
* @return Zend_Config
*/
public function getConfig()
{
if (!$this->config instanceof Zend_Config) {
$this->initConfig();
}
return $this->config;
}
/**
* @return Application
*/
public static function getInstance()
{
if (self::$application === null) {
self::$application = new Application();
}
return self::$application;
}
/**
* Load Configuration
*/
private function initConfig()
{
$configFile = $this->appDir . '/config/application.xml';
if (!is_readable($configFile)) {
throw new Application_Exception('Config file "' . $configFile . '" is not readable');
}
$config = new Zend_Config_Xml($configFile, 'test');
$this->config = $config;
}
// snip
/**
* @param string $appDir
*/
public function init($appDir)
{
$this->appDir = $appDir;
$this->initConfig();
// snip
}
public function run ($appDir)
{
$this->init($appDir);
$front = $this->initController();
$front->dispatch();
}
}
Ваш загрузочный файл будет выглядеть следующим образом:
require 'Application.php';
try {
Application::getInstance()->run(dirname(dirname(__FILE__)));
} catch (Exception $e) {
header("HTTP/1.x 500 Internal Server Error");
trigger_error('Application Error : '.$e->getMessage(), E_USER_ERROR);
}
Когда вы хотите получить доступ к конфигурации вы должны использовать следующее:
$var = Application::getInstance()->getConfig()->somevar;
Я определил короткую руку в каком-то месте, где я require_once (), в начале boostrap:
function reg($name, $value=null) {
(null===$value) || Zend_Registry::set($name, $value);
return Zend_Registry::get($name);
}
и в начальной загрузке у меня есть:
protected function _initFinal()
{
reg('::app', $this->getApplication());
}
, тогда я могу получить экземпляр Application где угодно, используя:
$app = reg('::app');
В большинстве приложений ZF объект приложения объявляется в глобальной области (см. public / index.php
в приложениях, созданных с помощью ZFW_DISTRIBUTION / bin / zf.sh
).
Это не совсем способ ZF, но вы можете получить доступ к объекту с помощью $ GLOBALS ['application']
.
Это похоже на обман, но если вам нужна производительность, это, вероятно, будет самым быстрым вариантом.
$manager = new My_Model_Manager($GLOBALS['application']->getOption('my'));