存储对值types的引用?

我正在写一个“监视器”对象,以方便debugging我的应用程序。 这个Monitor对象可以在运行时从IronPython解释器访问。 我的问题是,是否有可能在C#中存储一个值types的引用? 假设我有以下课程:

class Test { public int a; } 

我能以某种方式存储一个“指针”到“a”以便能够随时检查它的值吗? 是否有可能使用安全和托pipe代码?

谢谢。

您不能在字段或数组中存储对variables的引用。 CLR要求对variables的引用是(1)forms参数,(2)本地或(3)方法的返回types。 C#支持(1)而不是其他两个。

(另外:C#可以支持其他两种,实际上我已经编写了一个原型编译器来实现这些function,非常整洁(参见http://ericlippert.com/2011/06/23/ref- return-and-ref-locals / )。当然,我们必须编写一个algorithm来validation没有本地引用可能是指在一个现在被破坏的栈帧上的本地,这有点棘手,但是它是可行的,也许我们会在一个假设的未来版本的语言中支持这个(更新:它被添加到C#7!))

但是,通过将其放入一个字段或数组中,可以使variables具有任意长的生命周期。 如果你需要的是“我需要把一个别名存储到一个任意variables”的意义上的“引用”,那么没有。 但是如果你需要的是“我需要一个魔法令牌来让我读写一个特定variables”的意义上的引用,那么就使用一个委托或者一对委托。

 sealed class Ref<T> { private Func<T> getter; private Action<T> setter; public Ref(Func<T> getter, Action<T> setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } ... Ref<string> M() { string x = "hello"; Ref<string> rx = new Ref<string>(()=>x, v=>{x=v;}); rx.Value = "goodbye"; Console.WriteLine(x); // goodbye return rx; } 

外部局部variablesx将保持活着,直到rx被回收。

否 – 您不能直接在C#中将“指针”存储为值types。

通常情况下,您将持有对包含“a”的Test实例的引用 – 这使您可以访问(通过testInstance.a )。

这是一个我想到的模式,我发现自己使用了很多。 通常在传递属性作为父types的任何对象上使用的参数的情况下,但它对单个实例也同样适用。 (不适用于本地范围值typestho)

 public interface IValuePointer<T> { T Value { get; set; } } public class ValuePointer<TParent, TType> : IValuePointer<TType> { private readonly TParent _instance; private readonly Func<TParent, TType> _propertyExpression; private readonly PropertyInfo _propInfo; private readonly FieldInfo _fieldInfo; public ValuePointer(TParent instance, Expression<Func<TParent, TType>> propertyExpression) { _instance = instance; _propertyExpression = propertyExpression.Compile(); _propInfo = ((MemberExpression)(propertyExpression).Body).Member as PropertyInfo; _fieldInfo = ((MemberExpression)(propertyExpression).Body).Member as FieldInfo; } public TType Value { get { return _propertyExpression.Invoke(_instance); } set { if (_fieldInfo != null) { _fieldInfo.SetValue(_instance, value); return; } _propInfo.SetValue(_instance, value, null); } } } 

这可以像这样使用

 class Test { public int a; } void Main() { Test testInstance = new Test(); var pointer = new ValuePointer(testInstance,x=> xa); testInstance.a = 5; int copyOfValue = pointer.Value; pointer.Value = 6; } 

注意接口有一个更有限的模板参数集,这允许您将指针传递给不知道父types的东西。

你甚至可以实现另一个接口,没有任何模板参数调用任何值types的.ToString(不要忘记首先空检查)

你可以使用usafe代码从字面上取一个值types的指针

 public class Foo { public int a; } unsafe static class Program { static void Main(string[] args) { var f=new Foo() { a=1 }; // fa = 1 fixed(int* ptr=&f.a) { *ptr=2; } // fa = 2 } } 
 class Test { private int a; /// <summary> /// points to my variable type interger, /// where the identifier is named 'a'. /// </summary> public int A { get { return a; } set { a = value; } } } 

为什么要把自己写在复杂的代码中,把所有的标识符都链接到同一个位置? 创build一个属性,添加一些XML代码,以帮助您在课堂外,并使用您的代码中的属性。

我不知道如何存储一个指针,不认为这是可能的,但如果你只是想检查它的价值,我所知最安全的方法是创build一个variables的属性。 至less你可以随时检查它的属性,如果variables是静态的,你甚至不需要创build一个类的实例来访问variables。

物业有很多优点; types安全是一个,XML标签另一个。 开始使用它们!