【问题标题】:passing parameter that has the same name of class field variable in C#在C#中传递与类字段变量同名的参数
【发布时间】:2010-12-15 20:23:34
【问题描述】:

使用 C++,我可以编写如下代码。

class Terminal {
    int uid;

public:
    void SetUid(int uid) {self.uid = uid;}
};

我在 C# 中尝试过类似的事情,但出现错误。我尝试了以下方法,但它看起来很难看。

class Terminal {
    int uid;

public void SetUid(int uid_) {uid = uid_;}
}

当你想传递一个与C#中的类字段变量同名的参数时,你用什么?

【问题讨论】:

    标签: c#


    【解决方案1】:
    class Terminal {
        int uid;
    
        public void SetUid(int uid) { this.uid = uid; }
    }
    

    不过,我会考虑改用属性:

    class Terminal {
        public int Uid { get; set; }
    }
    

    Getter 和 setter 方法通常带有不恰当的 C# 设计的味道,因为属性为您提供了封装在语法糖中的 getter/setter 机制。

    【讨论】:

    • 与属性相比,getter/setter 方法有一个优势;它们可以用作委托引用。是的,您可以将属性包装在一个看起来像 setter 的 lambda 中,但这也开始产生异味,因为您基本上是在创建一个不增加任何值的方法。
    • @KeithS:您实际上可以在纯 IL 中直接为 getter/setter 创建一个委托。在 C# 中,您可以使用反射来执行此操作,如果您重用委托,这还不错:Func<int> getter = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), someTerminalReference, typeof(Terminal).GetProperty("Uid").GetGetMethod());
    • ... 实际上,我想我宁愿拥有 lambda。所有这些,与 ()=> Uid 相比。尽管它确实为调用堆栈添加了一个额外的层,但我认为它实际上会更高效,并且当然更易于阅读。
    • @KeithS:它更容易阅读,是的。至于性能,额外的方法不可能更快。它可能不会更慢,但它根本不可能更快。 (除非您计算委托构造。)
    【解决方案2】:

    你可以这样做。只需使用:

    public void SetUid(int uid) { this.uid = uid; }
    

    【讨论】:

      【解决方案3】:

      在C++中不是self,而是this,在C#中其实是一样的;

       public void SetUid(int uid)
       {
          this.uid = uid;
       }
      

      【讨论】:

      • self 不是来自 Pascal 之类的吗?
      • 我知道 Python 使用 self。自从我上次使用 Pascal 以来已经很长时间了,我不记得它使用了什么 :-)
      【解决方案4】:

      public void SetUid(int uid) {this.uid = uid;}

      【讨论】:

        【解决方案5】:

        我们不会将参数命名为与字段相同的名称,因为这会造成混淆。代码的阅读频率远高于编写代码的频率,因此可读性至关重要。必须在心理上解码哪个uid 是参数,哪个是字段,这是不值得的。

        我们实际上为我们的字段使用下划线前缀,以便立即清楚什么是字段以及什么是参数/本地。我知道不是每个人都喜欢这个约定,但我们觉得它很有帮助。

        此外,对于您正在编写的 SetXxx 方法,我们通常将参数命名为 value,遵循 C# 属性设置器的约定。由于只有一个参数,并且您已经从方法名称中知道它的含义,因此“value”与“uid”一样有意义。

        所以在我们的商店中,您的示例最终可能会是这样的:

        public class Terminal {
            private int _uid;
        
            public void SetUid(int value) {
                _uid = value;
            }
        }
        

        这是假设 uid 是只写的。如果它是可读写的,我们当然会使用属性而不是 getter/setter 方法。

        【讨论】:

        • @Phoera 除非他们最近更改了它,否则 MSDN 指南仅适用于共享库中可公开访问的成员。对私有字段使用下划线与 MSDN 指南不冲突,这是一种通用约定。 (但如果您有更新的链接与我所说的冲突,请在此处添加!)
        • C# 区分大小写,因此下划线的使用并不像在 VB 中那样重要。我的观点是,每个团队都应该就他们使用的约定达成一致,但这不应该被鼓励,因为 C# 有在不使用符号的情况下区分参数的方法,这会造成混乱。例如,您始终可以使用“this”或自动属性。这里有很多关于这个话题的讨论,所以,我只是不想重复它们。例如:stackoverflow.com/questions/3136594/…
        【解决方案6】:

        我已经开始养成在参数前加上“the”前缀的习惯,如果您更喜欢下划线,可以使用“theUID”或“the_uid”。

        public void SetUID(int theUID) {
            uid = theUID;
        }
        

        这比“值”更有帮助,尤其是当您有多个参数时:

        public Actor(String theName, String theFilm)
        {
            name = theName;
            film = theFilm;
        }
        

        (是的,我曾经使用过“this”,但发现它很麻烦且容易出错)

        【讨论】:

          猜你喜欢
          • 2011-07-27
          • 2018-03-14
          • 2011-04-03
          • 2017-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-08
          • 2023-03-27
          相关资源
          最近更新 更多