【问题标题】:What is the type of the 'value' reserved word in C# propertiesC# 属性中“值”保留字的类型是什么
【发布时间】:2010-10-04 07:36:40
【问题描述】:

我想知道属性中的“值”关键字采用什么类型。

所以:

public class Test
{
    string _numberAsString;
    int _number = -1;

    public Test() {}

    public string NumberAsString
    {
        get { return _numberAsString; }
        set { _numberAsString= value; }
    }

    public int Number
    {
        get { return int.Parse(_numberAsString); }
        set { _number = value; }
    }
}

//elsewhere
Test t = new Test();
t.Number = 5;

现在,正如我所料,这不会编译。 “值”的类型由属性的返回类型决定,对吗?我找不到任何效果,也许它太明显了(我没有阅读语言规范,大概那里有什么)。

我问,因为我想用一种类型设置属性,然后将其转换为 getter 的类型。我想这真的没有意义。

看来我必须通过创建几个方法来实现这一点。

【问题讨论】:

  • 嗯,你的代码确实编译了。至少,它对我有用......
  • 它也为我编译,但如果你调用,你会得到一个 ArgumentNullException: int val = t.Number;就在 //elsewhere 下的赋值之后,因为 _numberAsString 为空。如果你打电话 t.NumberAsString="6";首先然后调用 int val = t.Number; val 将为 6。您可能希望摆脱 _numberAsString 或 _number 并更改 Number 和 NumberAsString 以接受并返回您保留的任何一个。您可以使用 int 或 string 设置/获取,但实际数据只会在一个地方。
  • 嗯...注意自己。在你忘记你为什么问这个问题之前检查答案。现在我觉得很粗鲁,因为我不知道该接受哪个答案,因为我忘记了上下文。

标签: c# properties types keyword


【解决方案1】:

是的,“值”的类型由属性的返回类型决定。你到底想完成什么?您是否希望能够将 Number 或 NumberAsString 设置为有效值并从任一属性中返回结果?

如果是这种情况,您需要这样做:

public class Test
{
   string _numberAsString;
   int _number = -1;

   public Test() {}
   public string NumberAsString
   {
       get { return _numberAsString; }
       set { _numberAsString= value; }
   }
   public int Number
   {
       get { return int.Parse(_numberAsString); }
       set { _numberAsString = value.ToString(); }
   }
}

这将允许您这样做:

Test t = new Test();
t.Number = 5;
Console.WriteLine(t.NumberAsString); // should print out "5"
t.NumberAsString = "5";
Console.WriteLine(t.Number); // should print out "5"

对于采用不同类型的属性,您不能有 get 和 set。您唯一的选择是将其作为一种类型在内部存储,然后在 get 或 set(或两者)中执行从一种类型到另一种类型的转换。

【讨论】:

    【解决方案2】:

    setter 中值的类型是属性的类型——你不能将字符串传递给一个 int 的属性,这必须首先被解析为一个 int。

    .net 中的字符串不能被强制转换为任何其他类型(以 perl、awk 和许多其他动态语言允许的方式),它们只能被视为字符串或它们的父类对象。

    你可以这样做:

    private int _number;
    private string  _numberAsString;
    
    public string NumberAsString
    {
        get { return _numberAsString; }
        set { LinkedSet(value); }
    }
    
    public int Number
    {
        get { return _number; }
        set { LinkedSet(value); }
    }
    
    
    private void LinkedSet(string s)
    {
        this._number = int.Parse(s);
        this._numberAsString = s;
    }  
    
    private void LinkedSet(int i)
    {
        this._numberAsString = i.ToString();
        this._number = i;
    }  
    

    显然 NumberAsString setter 可以抛出 FormatException 而 Number setter 不能。

    我一般不建议这样做,除非您真的需要避免定期将数字转换为字符串和字符串转换为数字(此时您可以让设置者变得懒惰在他们对链接值的评估中 - 尽管将异常的语义从字符串的集合更改为 int 的获取 - 可能充其量是烦人的,或者最坏的情况是一个讨厌的错误。

    【讨论】:

      【解决方案3】:

      对我来说,允许在 NumberAsString 上设置一个 setter 是没有意义的。

      为什么不这样?:

      public class Test
      {
         int _number = -1;
      
         public Test() {}
         public string NumberAsString
         {
             get { return _number.ToString(); }
         }
         public int Number
         {
             get { return _number; }
             set { _number= value; }
         }
      }
      

      【讨论】:

        【解决方案4】:

        为什么不这样做

        Test t = new Test();
        t.Number = 5;
        Console.WriteLine(t.Number.ToString());
        

        令我震惊的是,您无缘无故地试图狡猾。

        我认为当方法更合适时,您会尝试在此处使用属性。属性不应该有任何不可预见的副作用,这将通过对其执行类型转换(如果可能的话)。

        【讨论】:

        • 这是一个与保留字“价值”相关的假设问题,但在我忘记了我在问什么之前我没有得到答案。很抱歉。
        猜你喜欢
        • 2015-09-30
        • 1970-01-01
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多