Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我应该在PHP中使用类似C的属性处理吗?_C#_Php_Oop - Fatal编程技术网

C# 我应该在PHP中使用类似C的属性处理吗?

C# 我应该在PHP中使用类似C的属性处理吗?,c#,php,oop,C#,Php,Oop,嘿,社区, 我在这里看到:使用 C#共有的一种属性处理类型,即: 如果在C#中,可以定义如下类: public class Person { private string _name; public string Name { get{ return _name; } set{ _name = value; } } } public class Person { private var $name; p

嘿,社区, 我在这里看到:使用 C#共有的一种属性处理类型,即: 如果在C#中,可以定义如下类:

public class Person 
{
    private string _name;
    public string Name
    {
        get{ return _name; }
        set{ _name = value; }
    }
}
public class Person
{
    private var $name;    

    public function Name() 
    {
        if(func_num_args() == 0) {    return $this->name;  } 
        else {$this->name = func_get_arg(0);  }
    }
}
那么为什么在php中定义类似的属性是明智的还是不明智的呢

public class Person 
{
    private string _name;
    public string Name
    {
        get{ return _name; }
        set{ _name = value; }
    }
}
public class Person
{
    private var $name;    

    public function Name() 
    {
        if(func_num_args() == 0) {    return $this->name;  } 
        else {$this->name = func_get_arg(0);  }
    }
}

如果需要对要设置的值进行一些额外的检查,您可能需要定义
getFoo
setFoo
方法,或者更好地使用。后者将给用户一种获得/设置本机属性的感觉。(后者是您在C#中所做的。只是每个类只有一个方法,不是很多。)

IMO,这在PHP中看起来并不干净。这就像你试图把C#方式塞进PHP,因为你认为这是C#的一个很好的特性

我把它看作:在PHP中,您正在为两个完全不同的事情创建一个函数,这是没有意义的。同时,在C#中,它是一个单一属性,它被设计为一个要设置/检索的对象的单一访问点。

将一个函数同时作为getter和setter违反了

在c#中,它只是语法上的糖分,并被转换为getter和setter,就像您应该用php编写它一样

事实上,在c#中,您可以通过编写

public string Name { get; set; }

编译器将生成一个私有的支持字段,并为您生成getter和setter函数。

这是明智之举,例如:

class Settings
{
    private $data = array();

    public function __call($key,$arguments = array())
    {
        return !count($arguments)) ? $this->data[$key] : $this->data[$key] = $arguments[0];
    }
}
然后做

$Settings = new Settings();
$Settings->name('hello');
$Settings->foo('bar');
现在已经创建了无限量的匿名函数,可以随时使用,通常使用两种方法构建,即
\uuuu get
\uu set
,这样您可以定义方法和变量的分离,示例如下

class Settings
{
    private $data = array();

    public function __set($key,$val)
    {
        $this->data[$key] = $val;
    }
    public function __get($key)
    {
        return $this->data[$key];
    }
}
这将允许您这样设置变量:

$Settings->foo = 'bar';
但您可以进一步创建一个变量注册表系统:

因此,基本上您可以将上述类从
设置
更改为
可变存储
,并执行以下操作:

class User extends VariableStorage{}
class Profile extends VariableStorage{}
这样使用:

$Profile = new Profile('Robert','Pitt',USER_PRIV_ADMIN);
$Profile->id = 56;
$Profile->userdata = $Database->GetUserData($Profile); //Reads $Profile->id

因此,只需定义一次方法,只要按照良好的设计构建继承结构,它就可以非常好地工作。

我个人在PHP中使用了类似的模式。我认为它是干净和相当有用的

private $name;
public function name($name = null)
{
    if ($name === null) return $this->name;
    $this->name = $name;
}
您甚至可以执行此操作以强制执行某些类型安全:

private $name;
public function name(string $name = null)
{
    if ($name === null) return $this->name;
    $this->name = $name;
}
您还可以强制设置/获取引用而不是副本:

private $name;
public function &name(string &$name = null)
{
    if ($name === null) return $this->name;
    $this->name = &$name;
}
这是完全有效的PHP,非常好地模仿了C

此外,各国:

单一责任原则是一种计算机编程原则,它规定每个模块或类应对软件提供的功能的单个部分负责,并且该责任应完全由类封装

因此,这并没有打破单一责任原则,因为这只是一个用于获取/设置类成员变量的类方法


这里唯一的缺点是,在类的实例上,必须调用函数来获取/设置成员变量,而不是真正的属性。您可以将此设计模式与PHP的“get”和“set”混合使用,但这只会增加开销。

一个问题:为什么?在普通的getter/setter语法(
getName()
setName($name)
)上,或者在神奇的方法(让你做
$foo->name='bar';echo$foo->name;
)上,这样做的目的是什么?Irwin-这种语法不是C所做的,或者看起来不是这样的。糟糕的类比。我的想法完全正确。在尝试将功能从一种语言移植到另一种语言之前,请仔细考虑。PHP通过其神奇的方法处理getter/setter的繁琐工作。你可能想看看这些。是的,它违反了(对于例程而不是类)。我相信在我的帖子中,只要你做得好,这个方法就可以实现。jQuery(一个优秀的软件)一直都在这样做
x.html(foo)
设置值,
x.html()
返回。这是一款很棒的软件,尽管如此,他们还是有意识地决定打破SRP,只有严格遵守他们的标准才能做到这一点。所有/大多数setter(通过输入调用的方法)返回一个jQuery对象,该对象允许一个可链接的接口。而且getter有时是无参数的。像
.attr('name')
是一个getter,而
.attr('name',value)
是一个setter。这就是开始让人困惑的地方。因为它们的函数根据参数做不止一件事,所以库的使用者需要理解它。这可能会让人困惑。+1,我还要提到重载只模拟属性,而不是替换属性。php中还没有对属性的真正支持。好的,您已经实现了一个“属性包”(使用任何名称附加属性)。一个有用的概念。我认为值得一提的是,这可以扩展为允许一组特定的属性名,方法是使用一个具有私有静态字段(该字段是有效属性名数组)的子类,并检查名称是否在该数组中,以拒绝任何其他属性名。次要提示:使用
$name
作为参数名会让人困惑。更合适的名称是
$value