zoukankan      html  css  js  c++  java
  • 让泛型类支持数值计算

    class Ref<T>
    {
        public T Value;
        public Ref<T>()
        {
        }
        public Ref<T>(T value)
        {
            this.Value = value;
        }
    }

    Then use it like this:

    class A
    {
        Ref<int> x;
        public A(Ref<int> x)
        {
            this.x = x;
        }
        public void Increment()
        {
            x.Value++;
        }
    }
    
    ...
    
    Ref<int> x = new Ref<int>(7);
    A a = new A(x);
    a.Increment();
    Debug.Assert(x.Value == 8);

    Note that the Ref<T> class here is a reference to a value - not a reference to a variable. If you want a reference to a variable, use Eric Lippert's solution (as pointed out by Filip).

    public class StringWrapper
     {
       public string s;
       public StringWrapper(string s)
       {
         this.s = s;
       }
    
       public string ToString()
       {
         return s;
       }
     }
    
     public class X
     {
      public X()
      {
       StringWrapper example = new StringWrapper("X");
       new Z(example)
       System.Diagnostics.Debug.WriteLine( example );
      }
     }
    
     public class Z
     {
      private StringWrapper _Example;
      public Z( StringWrapper example )
      {
       this._Example = example;
       this._Example.s += " (Updated By Z)";
      }
     }

    As others have noted, you cannot have a field of "ref to variable" type. However, just knowing that you cannot do it is probably unsatisfying; you probably also want to know first, why not, and second, how to get around this restriction.

    The reason why is because there are only three possibilities:

    1) Disallow fields of ref type

    2) Allow unsafe fields of ref type

    3) Do not use the temporary storage pool for local variables (aka "the stack")

    Suppose we allowed fields of ref type. Then you could do

    publicrefint x;void M(){int y =123;this.x =ref y;}

    and now y can be accessed after M completes. This means that either we're in case (2) -- accessing this.x will crash and die horribly because the storage for y no longer exists -- or we're in case (3), and the local y is stored on the garbage collected heap, not the temporary memory pool.

    We like the optimization that local variables be stored on the temporary pool even if they are being passed by ref, and we hate the idea that you could leave a time bomb around that could make your program crash and die later. Therefore, option one it is: no ref fields.

    Note that for local variables that are closed-over variables of anonymous functions we choose option (3); those local variables are not allocated out of the temporary pool.

    Which then brings us to the second question: how do you get around it? If the reason you want a ref field is to make a getter and setter of another variable, that's perfectly legal:

    sealedclassRef<T>{privatereadonlyFunc<T> getter;privatereadonlyAction<T> setter;publicRef(Func<T> getter,Action<T> setter){this.getter = getter;this.setter = setter;}public T Value{ get {return getter();}set{ setter(value);}}}...Ref<int> x;void M(){int y =123;
        x =newRef<int>(()=>y, z=>{y=z;});
        x.Value=456;Console.WriteLine(y);// 456 -- setting x.Value changes y.}

    And there you go. y is stored on the gc heap, and x is an object that has the ability to get and set y.

    Note that the CLR does support ref locals and ref returning methods, though C# does not. Perhaps a hypothetical future version of C# will support these features; I have prototyped it and it works well. However, this is not real high on the priority list, so I wouldn't get my hopes up.

  • 相关阅读:
    无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)
    ASP.NET Web API 数据验证
    css控制文字显示长度,超过用省略号替代
    Android 屏幕适配
    Android ListView item项 显示动画
    Android 定位地理坐标体系
    Android 解压缩功能
    Android 魅族等SmartBar适配
    Android 推送实现
    Android Mvc 实现
  • 原文地址:https://www.cnblogs.com/zeroone/p/3715350.html
Copyright © 2011-2022 走看看