我正在为初学者读一本关于C#的书,而我正处于“理解价值观和参考资料”这一部分,但有一些我不理解的东西。我所看到的是,书籍试图向我解释这一点(我已经在Youtube的几个教程视频中看到了这一点),该类正被用来创建一个对象(? ?)班级。我已经阅读了整个前一章,其中也发生过这种情况,我不太明白它,假设在下一章中它会变得更加清晰。它没有变得更清楚,所以我不认为继续直到我理解我之前解释过的东西的概念为止是一个好主意。
以下部分是本书的一部分:
请记住,要初始化一个引用变量,例如类,你 可以创建类的新实例并分配引用 变量到新对象,如下所示:
Circle c = new Circle(42);
Circle copy = new Circle(99);
//Circle refc = c;
...
copy = c;
我可以用这个例子中的代码做什么,为什么它很方便?示例+解释将非常受欢迎。提前谢谢!
答案 0 :(得分:9)
听到它的声音,你还没有得到这本书的解释:
下面的眼睛读取2个圆圈的大小为3和4,并取第一个副本并使其为5 ..除非你打印出来,这不是它的工作方式。
class Program
{
static void Main(string[] args)
{
circle a = new circle(3);
circle b = new circle(4);
circle d = a;
d.Diameter = 5;
Console.WriteLine("a is {0}", a.Diameter); // shows 5
Console.WriteLine("b is {0}", b.Diameter); // shows 4
Console.WriteLine("d is {0}", d.Diameter); // shows 5
}
}
class circle
{
public int Diameter;
public circle(int d)
{
Diameter = d;
}
}
因为你没有为d创建一个新的圆圈,实际上d是a的别名,所以,正如某人的名字是Peter,他也可以被称为Pete。
答案 1 :(得分:5)
请记住,要初始化引用变量(如类),可以创建类的新实例并将引用变量分配给新对象, [sic]
他展示了参考和价值类型之间的区别。使用值类型,它已经初始化。
double d;
您无需再做任何事情。对于类或引用类型,您必须为它提供一个对象的实例。
Circle c;
尚未分配对象。
d = c.Radius
错误。引用未指向对象。内存访问违规。
Circle c = new Circle();
现在确实如此。
答案 2 :(得分:4)
好吧,它可以方便,并且没有必要总是有可能为你的类型引用分配一个新对象的位置。在这种情况下,在最后一行copy = c;
上,您说复制现在指向由c
分配的内存位置,换句话说,在该行之后它们都指向相同强>记忆位置。
答案 3 :(得分:3)
在面向对象的编程中为您提供速成课程相当复杂,但这就是您目前所需要的:您目前需要了解 OO编程这是一种编程范式,许多编程语言当然也有C#。
您在上述帖子中描述的问题如下:
在 oo-prgramming 中,您正在编写由(大致)字段和方法组成的类。这些类有一个静态字符,并且在您的应用程序开发期间存在(请不要对我在这里使用的单词static和关键字' static ')。在应用程序运行期间,您可以使用这些 static * classes *来创建这些类的对象,这意味着特定类可用作任意数量的对象都是相同的。与类相比,这些对象也称为类的实例,并且仅在应用程序的运行时期间存在。对象动态。
非常简短:当你有课时
class House {
// ...
}
你有一个房子的静态描述,你可以用它来创建动态 *对象*即房屋。您正在使用所谓的 new-operator 执行此操作(使用C#和其他现代语言,如Java):
House house = new House();
你在这里做的是声明一个类型为House的变量。您使用 class House自行定义的类型。这是这一部分:
House house;
到目前为止,它只是House类型的变量,它什么都不做。这里重要的术语是它指向什么都没有,这没有什么被称为 null 。
然后,您可以使用以下语法创建此类的实例(动态对象):
house = new House();
现在您已经创建了一个对象,并让您的变量指向对象。从现在开始,您可以使用变量house来引用此对象。
我告诉你这是指出你在上面的帖子中提到的一个重要问题:价值类型和推荐类型的差异。
您在前几行中所做的是您创建了一个指向对象的新变量。这(大致再次)称为引用类型。与之相反,您可以使用原始类型,例如 int , byte , short 等。
使用
int i = 4;
您再次声明 变量。但这次变量直接保持它的价值而不是指向它。这称为值类型。
值类型和引用类型之间的差异非常重要,例如,当您将参数这样的变量传递给方法时。
答案 4 :(得分:2)
我会尝试解决这个问题,因为那太可怕了。
原件:
请记住,要初始化引用变量(如类),可以创建类的新实例并将引用变量分配给新对象,如下所示:
修正:
请记住,要初始化引用类型的变量,可以创建该变量类型的新实例,并将变量更改为指向新对象,如下所示:
虽然为什么那应该是你应该记住的东西,但我不知道。是的,你可以创建对同一个对象的多个引用,这本身就很有用,但它不会让我觉得它是一个特别有用的初始化策略。
更好地修复了:
你可以让引用类型的变量引用同一个实例,但要记住变量本身不是别名,所以覆盖一个不会改变另一个。
答案 5 :(得分:1)
您可以将类视为数据的模式,例如规范或蓝图。当您使用“new”关键字时,您告诉计算机使用该蓝图为您创建对象。对象是该类的具体实例。
因此,如果您有蓝图(类定义),您可以根据需要多次调用new来生成该类的多个实例。如果您拥有汽车蓝图,就可以根据需要制作多辆汽车副本(给定足够的材料)。
这样做:
Circle c = new Circle(42);
Circle copy = new Circle(99);
告诉计算机使用Circle类定义和实例两个对象(因此计算机内存中有两个圆圈)。这些是具有不同属性的不同对象(一个具有半径42,另一个具有99个)。它们被分配到变量c和copy。
您执行copy = c的代码的最后一行;将变量c指向的圆圈放入变量副本。
答案 6 :(得分:1)
班级定义是蓝图。把它想象成一座房子。每次实例化一个对象Circle c = new Circle(42)
时,你构建的是一个带有蓝色图案的房子。每个房子都有一个街道上的地址(记忆中的地址)。
您拥有的每个变量都像一张纸条,上面列出了房子的地址。所以你在123大街上建造了一座蓝色的2层楼房子,在一张纸上写下了123条主要街道并标上了纸张“A”。接下来,你将在456 King Street建造一座红色的4层楼房子,然后将该地址写在纸上并标记纸张“B”。接下来,你得到一张纸,写下你所建造的第一所房子的地址(123 Main Street)并标记纸张'C'。
然后你去找一位画家,让他把房子漆成黄色。你给他一张纸'C'。我们的例子中只有两个房子。由于C和A“指向”相同的地址,他们现在指向一个黄色的房子。
House a = new House( blue, 2 );
House b = new House( red, 4 );
House c = a;
c.Color = yellow;
//Now a.Color is yellow as well
答案 7 :(得分:1)
变量不是对象,它只是对象的引用。因此,例如,在以下示例中,有两个变量都引用同一个对象:
Label label1 = new Label();
Label label2 = label1;
label1.Text = "1";
label2.Text = "2";
执行该代码后,您会看到label1.Text
等于" 2"而不是" 1"。这是因为它们都引用了相同的Label
对象,因此当您设置label2.Text
时,它将针对这两个变量进行更改。但是,如果您实例化了两个单独的标签对象,则结果会有所不同,例如:
Label label1 = new Label();
Label label2 = new Label();
label1.Text = "1";
label2.Text = "2";
在第二个示例中,每个变量指向一个不同的Label
对象(即Label类的不同实例)。因此,运行此代码后,label1.Text
将等于" 1"并且label2.Text
将等于" 2",正如您所期望的那样。
有充分的理由说明为什么这两个选项都很重要并且可供您使用。例如,假设您要创建一个设置Text
的{{1}}属性的方法,例如:
Label
你可以这样称呼方法:
void SetLabelText(Label labelToSet)
{
labelToSet.Text = "text";
}
在这种情况下,Label label1 = new Label();
SetLabelText(label1);
方法中的labelToSet
变量将引用与SetLabelText
变量相同的对象,因此当' label1
设置{{ 1}}到"文字",它没有创建新的SetLabelText
,它只是在传递的现有labelToSet.Text
对象上设置文本方法的一个参数,这正是你想要发生的。
由于任何变量都可以设置为新对象或现有对象,因此它被视为" null"直到它被分配给一个对象。正如我刚开始所说,变量不是对象,它只是对象的引用。如果变量根本没有引用任何对象(它的初始状态),那么它是Label
并且如果您尝试使用它将抛出异常。例如:
Label
您可以根据需要声明任意数量的变量,但它们都将为null
,直到您实际实例化至少一个对象并将其设置为它。要实例化对象(即创建类的新实例),您必须使用Label label1;
label1.Text = "1"; // Throws a null reference exception
关键字(例如null
)。
然而,到目前为止,我所说的一切只适用于"参考类型" (类)。但"价值类型"的情况并非如此。 (结构)。当您将变量声明为值类型时,出于所有实际目的,它实际上是对象。许多简单数据类型(如new
)都是值类型。例如:
new Label()
运行上述代码后,int
将等于int x;
int y;
x = 1;
y = x;
y = 2;
,x
将等于1
。设置y
不会导致2
引用与y = x
相同的对象。而是将值从y
复制到x
,从而创建新的值类型对象。
答案 8 :(得分:0)
如果我们在这种情况下引用人类,那么这个类定义什么是人类以及它可以做什么(它的成员如高度,宽度等,它的方法是eat(),drink()等),一个对象代表实际的人(一个名叫安德鲁的人,身高可以吃喝)
答案 9 :(得分:0)
如果我错了,请纠正我,但是当我查看代码时,我看到正在创建的两个对象并指向一个值是他们自己的内存位置。
副本= c; line只是说复制对象不会指向c对象的内存位置而不是它首先设置的位置。
答案 10 :(得分:0)
在您提供的示例中,与书籍提供的许多示例一样,您将看到最基本的案例。在您真正深入了解代码之前,很难理解使用此类功能的最佳方法。
我不知道这是否完全正确,但我会使用这样的方式是:
private double GetArea(Circle c)
{
//this will be a default circle should the passed in circle be invalid
Circle toCalc = new Circle(5);
//check to make sure c is valid
if(c != null)
toCalc = c;
return Math.pow(toCalc.Radius, 2) * Math.Pi;
}
由于toCalc是一个类而不是原始数据类型,因此必须对其进行初始化以便编译代码。如果未初始化,编译器将给出一些错误,例如“toCalc可能未初始化”。