繁体   English   中英

这是C#在类属性上设置getter和setter的正确方法吗?

[英]Is this the correct way C# set getter and setter on class property?

如您所见,我为类属性创建了getter和setter方法。 我想知道,像在下面一样进行设置是否可以? 我没有在get中使用private变量,可以吗?还是应该使用它? 如果我的方法错误,有人可以纠正我这种情况下我的课程的样子吗? 该类是CloneAble

public int? Id { get; set; }
public string Code { get; set; }

private string _name;
public string Name
{
    get
    {
        if (this.Id == null)
            return null;
        else
            return this.Id+ "/" + this.Code;
    }
    set
    {
        if (this._name != value)
        {
            this._name= value;
        }
    }
}

public bool IsValid
{
    get
    {
        if (this.Id == null)
            return false;
        else
            return true;
    }
}

该类是可克隆的:

public object Clone()
{
    var elem= new Element();

    this.SetPropertyValues(elem);

    return elem;
}

private void SetPropertyValues(elem)
{
    var propertyInfo = this.GetType().GetProperties().Where(p => p.CanWrite && (p.PropertyType.IsValueType || p.PropertyType.IsEnum || p.PropertyType.Equals(typeof(System.String))));

    foreach (PropertyInfo property in propertyInfo)
    {
        if (property.CanWrite)
        {
            property.SetValue(elem, property.GetValue(this, null), null);
        }
    }
}

我认为您可以通过简化克隆方法来摆脱烦恼:

// Private parameterized CTOR
private Element( int id, string code ) 
{ 
    this.Id = id;
    this.Code = code;
}

// Simplyfied Clone
public object Clone()
{
    return new Element(Id, Code);
}

现在,您可以拥有只读的“属性名称” 和“克隆”:

public string Name => $"{Id}/{Code}";

该代码有效,但是_name什么? 您可以设置其值,但不能相反。 另外,由于Id是公共属性,因此创建IsValid并不是很有用。 您可以简单地创建一个值为this.Id != wrongValue并将Id this.Id != wrongValue私有。

结果将如下所示:

private int Id { get; set; }
public string Code { get; set; }

private readonly int IMPOSSIBLE_ID = -1000;

private string _name;
public string Name
{
    get {
        return (this.Id == null) ? null : this.Id+ "/" + this.Code;
    }
    set {
        if (this._name != value)
            this._name= value;
    }
}

public bool IsValid() => return this.Id != IMPOSSIBLE_ID;

UPDATE:现在, Id是可为空的整数

private int? Id { get; set; }
public string Code { get; set; }

private string _name;
public string Name
{
    get {
        return (this.Id == null) ? null : this.Id+ "/" + this.Code;
    }
    set {
        if (this._name != value)
            this._name= value;
    }
}

public bool IsValid() => return this.Id != null;

首先,因为intstruct ,所以int Id永远不能为null 这就是this.Id == null 始终为 true 您可以使Id可为

 public int? Id { get; set; }

或将this.Id == null更改为this.Id == 0

 // Let Id be nullable 
 public int? Id { get; set; }
 public string Code { get; set; }

由于可以轻松计算Name ,因此您不需要_name Name设置器的另一个问题:您可以"bla-bla-bla" Name "bla-bla-bla"分配"bla-bla-bla" ,然后再次阅读并得到意外的信息:

 var demo = MyClass();

 // "0/"
 Console.WriteLine(demo.Name);

 demo.Name = "123/Test";

 // "0/" instead of expected "123/Test";
 Console.WriteLine(demo.Name);   

因此,我建议您删除二传手:

 public string Name {
   get {
     return Id.HasValue
       ? $"{Id}/{Code}"
       : ""; // often, it's better return an empty string, not null
   }
 }   

或实现某种解析

 public string Name {
   get {
     return Id.HasValue
       ? $"{Id}/{Code}"
       : ""; // often, it's better return an empty string, not null
   }
   set {
     if (string.IsNullOrEmpty(value)) {
       Id = null;
       Code = ""; // often, it's better return an empty string, not null
     } 
     else {
       string[] parts = string.Split(new char[] {'/'}, 2);

       if (string.IsNullOrEmpty(parts[0])) {
         Id = null;
         Code = parts.Length > 1 ? parts[1] : ""; 
       }
       else if (int.TryParse(parts[0], out int id)) {
         Id = id;
         Code = parts.Length > 1 ? parts[1] : ""; 
       } 
       else 
         throw new FormatException("Name is inincorrect format.");
     }
   }
 }   

最后,可以将IsValid缩短为

 public bool IsValid => Id.HasValue;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM