C# - 检测对象引用何时更改

时间:2022-01-26 16:53:58

Supose that:

object x;

void GiveMeARef(ref object obj)
{
   x = obj;
}

So I want that X change this value when Y is changed. For instance:

所以我希望X在Y改变时改变这个值。例如:

Y = new MyObject;
GiveMeARef(Y); //So x == Y;
Y = new OtherObject; // I want that X continues equals to Y, but it doesn't:\

Anyone knows how I can do this in C# if it is possible?

任何人都知道如果可能的话我怎么能在C#中做到这一点?

Sorry about my poor english

抱歉我的英语不好

Thanks in advance

提前致谢

7 个解决方案

#1


This code smells of a larger problem ... but why not just do:

这段代码闻起来有一个更大的问题......但为什么不这样做呢:

var y = new MyObject();
GiveMeARef(ref y);
var z = new MyObject();

No need to reuse y.

无需重复使用y。

#2


without getting into low-level debugging techniques (like what Visual Studio uses when it's debugging your code), I don't think there's a straightforward way to do this.

没有进入低级调试技术(就像Visual Studio在调试代码时使用的那样),我认为没有一种直接的方法可以做到这一点。

What you're looking for is an alias, not a reference, and to my knowledge, that isn't supported by the CLR.

您正在寻找的是别名,而不是参考,据我所知,CLR不支持。

You might be able to do it by writing unsafe code, but I would suspect that there might be some significant side-effects and complications from doing this.

您可以通过编写不安全的代码来实现,但我怀疑这样做可能会产生一些重大的副作用和并发症。

#3


It really isn't clear to me what you are trying to do, but I'd be using a property:

我真的不清楚你想要做什么,但我会使用一个属性:

private SomeType y;
public SomeType Y {
   get { return y;}
   set {
       if(y!=value) {
           y = value;
           // run any "things to do when Y changes" code
           OnYChanged();
       }
   }
}
public event EventHandler YChanged;
protected virtual void OnYChanged() {
    EventHandler handler = YChanged;
    if(handler!=null) handler(this, EventArgs.Empty);
}

Now you can watch for changes to obj.Y in 3 different ways:

现在,您可以通过3种不同方式观察对obj.Y的更改:

  • in the Y setter
  • 在Y setter

  • via the YChanged event
  • 通过YChanged活动

  • by subclassing and overriding OnYChanged
  • 通过子类化和重写OnYChanged

#4


It seems like you want X to be a pointer to Y. Pointers aren't supported directly in C# (only in unsafe code) but you can achieve this properly by a litte hack with closures/lambda-expressions.

看起来你希望X成为指向Y的指针。指针不是直接在C#中支持的(仅在不安全的代码中),但你可以通过带有闭包/ lambda表达式的litte hack来正确实现。

Try converting this VB-tip to C# (Pointer<T>-Structure)

尝试将此VB-tip转换为C#(Pointer -Structure)

#5


There is no way to do what you are attempting (directly).

没有办法做你正在尝试的(直接)。

The closest thing I can think of would be to have Y be encapsulated inside of some other class, and have GiveMeARef() take the class instance instead of Y directly. This would look something like:

我能想到的最接近的事情是将Y封装在其他类中,并让GiveMeARef()直接使用类实例而不是Y.这看起来像是这样的:

myClass.Y = new MyObject();
GiveMeARef(ref myClass);
myClass.Y = new MyObject();

Then you'd be able to still have the internal reference find Y - even though it wasn't staying exactly the same.

那么你仍然可以让内部参考找到Y - 即使它没有保持完全相同。

#6


The easiest solution is to assign values to Y using a property, and update X in the setter function:

最简单的解决方案是使用属性为Y赋值,并在setter函数中更新X:

private MyObject m_Y = new MyObject();

public MyObject Y
{
     get { return m_Y; }
     set
     {
         m_Y = value;
         X = value;      // Here ...
     }
}

Another solution is creating a new class, MyObjectWrapper, and deal with it instead ...

另一个解决方案是创建一个新类MyObjectWrapper,然后处理它......

Another thing, there isn't any point of the 'ref' in GiveMeARef(ref object obj) .. it's already passed by reference.

另一件事,GiveMeARef(ref object obj)中没有任何'ref'点。它已经通过引用传递了。

#7


This would also achieve the result, keeping the assignment at the time of the "new" operation, assuming that in your example you are using many different news and want X to be updated each time.

这也将实现结果,在“新”操作时保持分配,假设在您的示例中您使用了许多不同的新闻并且希望每次都更新X.

private static object x;
private static object CreateNew(Type t) {
    object temp;
    temp = System.Activator.CreateInstance(t);
    x = temp;
    return temp;                      
}

static void Main(string[] args) {

    object o = CreateNew(typeof(int));           
    o = CreateNew(typeof(long));


}

Where you use reflection to create the instance of the object and assign it to the keeper variable at the same time. It very much depends on what the nature of the problem is as to which is the appropriate solution.

使用反射创建对象实例并同时将其指定给守护程序变量的位置。这在很大程度上取决于问题的本质是什么是适当的解决方案。

#1


This code smells of a larger problem ... but why not just do:

这段代码闻起来有一个更大的问题......但为什么不这样做呢:

var y = new MyObject();
GiveMeARef(ref y);
var z = new MyObject();

No need to reuse y.

无需重复使用y。

#2


without getting into low-level debugging techniques (like what Visual Studio uses when it's debugging your code), I don't think there's a straightforward way to do this.

没有进入低级调试技术(就像Visual Studio在调试代码时使用的那样),我认为没有一种直接的方法可以做到这一点。

What you're looking for is an alias, not a reference, and to my knowledge, that isn't supported by the CLR.

您正在寻找的是别名,而不是参考,据我所知,CLR不支持。

You might be able to do it by writing unsafe code, but I would suspect that there might be some significant side-effects and complications from doing this.

您可以通过编写不安全的代码来实现,但我怀疑这样做可能会产生一些重大的副作用和并发症。

#3


It really isn't clear to me what you are trying to do, but I'd be using a property:

我真的不清楚你想要做什么,但我会使用一个属性:

private SomeType y;
public SomeType Y {
   get { return y;}
   set {
       if(y!=value) {
           y = value;
           // run any "things to do when Y changes" code
           OnYChanged();
       }
   }
}
public event EventHandler YChanged;
protected virtual void OnYChanged() {
    EventHandler handler = YChanged;
    if(handler!=null) handler(this, EventArgs.Empty);
}

Now you can watch for changes to obj.Y in 3 different ways:

现在,您可以通过3种不同方式观察对obj.Y的更改:

  • in the Y setter
  • 在Y setter

  • via the YChanged event
  • 通过YChanged活动

  • by subclassing and overriding OnYChanged
  • 通过子类化和重写OnYChanged

#4


It seems like you want X to be a pointer to Y. Pointers aren't supported directly in C# (only in unsafe code) but you can achieve this properly by a litte hack with closures/lambda-expressions.

看起来你希望X成为指向Y的指针。指针不是直接在C#中支持的(仅在不安全的代码中),但你可以通过带有闭包/ lambda表达式的litte hack来正确实现。

Try converting this VB-tip to C# (Pointer<T>-Structure)

尝试将此VB-tip转换为C#(Pointer -Structure)

#5


There is no way to do what you are attempting (directly).

没有办法做你正在尝试的(直接)。

The closest thing I can think of would be to have Y be encapsulated inside of some other class, and have GiveMeARef() take the class instance instead of Y directly. This would look something like:

我能想到的最接近的事情是将Y封装在其他类中,并让GiveMeARef()直接使用类实例而不是Y.这看起来像是这样的:

myClass.Y = new MyObject();
GiveMeARef(ref myClass);
myClass.Y = new MyObject();

Then you'd be able to still have the internal reference find Y - even though it wasn't staying exactly the same.

那么你仍然可以让内部参考找到Y - 即使它没有保持完全相同。

#6


The easiest solution is to assign values to Y using a property, and update X in the setter function:

最简单的解决方案是使用属性为Y赋值,并在setter函数中更新X:

private MyObject m_Y = new MyObject();

public MyObject Y
{
     get { return m_Y; }
     set
     {
         m_Y = value;
         X = value;      // Here ...
     }
}

Another solution is creating a new class, MyObjectWrapper, and deal with it instead ...

另一个解决方案是创建一个新类MyObjectWrapper,然后处理它......

Another thing, there isn't any point of the 'ref' in GiveMeARef(ref object obj) .. it's already passed by reference.

另一件事,GiveMeARef(ref object obj)中没有任何'ref'点。它已经通过引用传递了。

#7


This would also achieve the result, keeping the assignment at the time of the "new" operation, assuming that in your example you are using many different news and want X to be updated each time.

这也将实现结果,在“新”操作时保持分配,假设在您的示例中您使用了许多不同的新闻并且希望每次都更新X.

private static object x;
private static object CreateNew(Type t) {
    object temp;
    temp = System.Activator.CreateInstance(t);
    x = temp;
    return temp;                      
}

static void Main(string[] args) {

    object o = CreateNew(typeof(int));           
    o = CreateNew(typeof(long));


}

Where you use reflection to create the instance of the object and assign it to the keeper variable at the same time. It very much depends on what the nature of the problem is as to which is the appropriate solution.

使用反射创建对象实例并同时将其指定给守护程序变量的位置。这在很大程度上取决于问题的本质是什么是适当的解决方案。