在C#中创建一个不包含状态的对象实例时会发生什么?

liq*_*ice 8 c# class

我认为在算法编程方面没问题,如果这是正确的术语?我曾经在20世纪80年代作为业余爱好使用turbo pascal和8086汇编语言.但是只有非常小的项目,而且从那以后的20年里,我还没有真正做过任何编程.因此,我正像溺水的游泳运动员一样努力去理解.

所以也许这是一个非常非常的问题,或者我根本没有任何意义,但是我说有一个像这样的对象:

class Something : IDoer
{
    void Do(ISomethingElse x)
    {
         x.DoWhatEverYouWant(42);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我做

var Thing1 = new Something();
var Thing2 = new Something();

Thing1.Do(blah);
Thing2.Do(blah);
Run Code Online (Sandbox Code Playgroud)

Thing1 = Thing2?"new Something()"会创造什么吗?或者与静态类没什么不同,除了我可以传递它并将其交换出来等.

Thing1(blah)和Thing2(blah)对象在内存中的"Do"程序是否在同一位置?我的意思是在执行它时,是否意味着有两个Something.Do程序或只有一个?

Dan*_*Tao 12

它们是两个独立的对象; 他们只是没有国家.

考虑以下代码:

var obj1 = new object();
var obj2 = new object();

Console.WriteLine(object.ReferenceEquals(obj1, obj2));
Run Code Online (Sandbox Code Playgroud)

它会输出False.

仅仅因为一个对象没有状态并不意味着它不像任何其他对象那样被分配.它只需要很小的空间(就像一个object).

在回答问题的最后部分时:只有一种Do方法.方法不是按实例存储,而是按类存储.如果你考虑一下,每个实例存储它们会非常浪费.DoSomething对象的每个方法调用都是同一组指令; 来自不同对象的调用之间的所有不同之处是底层对象的状态(如果Something类具有任何开始状态,那就是).

这意味着类对象上的实例方法在行为上与静态方法完全相同.

您可能会认为它好像所有实例级方法都被秘密翻译如下(我不是说这是严格正确的,只是你可以这样想它并且它确实有意义):

// appears to be instance-specific, so you might think
// it would be stored for every instance
public void Do() {
    Do(this);
}

// is clearly static, so it is much clearer it only needs
// to be stored in one place
private static Do(Something instance) {
    // do whatever Do does
}
Run Code Online (Sandbox Code Playgroud)

有趣的旁注:上面假设的"翻译"几乎解释了扩展方法的工作方式:它们是静态方法,但通过用this关键字限定第一个参数,它们看起来像实例方法.


Bri*_*eon 7

内存中绝对有两个不同的对象.每个对象将在堆上消耗8个字节(至少在32位系统上); 4表示同步块,4表示类型句柄(包括方法表).除了系统定义的状态数据之外,在您的情况下没有其他用户定义的状态数据.

Something.Do方法的代码有一个实例.每个对象保存的类型句柄指针是CLR如何定位类的不同方法.因此,即使内存中有两个不同的对象,它们也会执行相同的代码.由于Something.Do声明为实例方法,因此它将在this内部传递一个指针,以便代码可以根据调用该方法的对象修改正确的实例成员.在你的情况下,Something类没有实例成员(因此没有用户定义的状态),所以这是无关紧要的,但仍然会发生.


Dav*_*d M 5

不,他们不一样.它们是该类的两个独立实例Something.它们碰巧被同样实例化,就是全部.