C #에서 참조 유형과 값 유형의 차이점은 무엇입니까?
몇 달 전에 어떤 사람이이 질문을했지만 자세히 설명 할 수 없었습니다. C #에서 참조 형식과 값 형식의 차이점은 무엇입니까?
나는 그 값 유형을 알고 int
, bool
, float
, 등 참조 유형은 delegate
, interface
, 등 또는도이 잘못?
전문적인 방식으로 설명해 주시겠습니까?
귀하의 예 때문에 동안 약간의 홀수 int
, bool
및 float
특정 유형, 인터페이스 및 대의원이 있습니다 가지 유형의 - 단지 같은 struct
과 enum
값 형식의 종류입니다.
이 기사에서 참조 유형 및 값 유형 에 대한 설명을 작성 했습니다 . 혼란스러워하는 부분이 있으면 기꺼이 확장하겠습니다.
"TL; DR"버전은 특정 유형의 변수 / 표현식 값이 무엇인지 생각하는 것입니다. 값 유형의 경우 값은 정보 자체입니다. 참조 유형의 경우 값은 null 일 수있는 참조이거나 정보를 포함하는 개체를 탐색하는 방법 일 수 있습니다.
예를 들어, 변수를 종이처럼 생각하십시오. "5"또는 "false"라는 값이 적혀있을 수 있지만 내 집은 가질 수 없습니다 . 내 집 으로 가는 길 을 알려야합니다. 이러한 지침은 참조와 동일합니다. 특히 두 사람이 내 집으로가는 방향이 같은 다른 종이를 가질 수 있습니다. 한 사람이 그 지시를 따라 내 집을 빨간색으로 칠하면 두 번째 사람도 그 변화를 볼 수 있습니다. 둘 다 종이에 내 집 사진 을 따로 찍었 다면 한 사람이 종이에 색칠을하더라도 다른 사람의 종이를 전혀 바꾸지 않을 것입니다.
값 유형 :
메모리 주소가 아닌 일부 값을 보유합니다.
예:
구조
저장:
TL; DR : 변수의 값은 해제 될 때마다 저장됩니다. 지역 변수는 예를 들어 스택에 살고 있지만 구성원으로 클래스 내에 선언 때 단단히가 선언 된 클래스와 결합 된 힙에 살고있다.
긴 : 그들이 선언 된 곳 따라서 값 유형이 저장됩니다. 예 : int
지역 변수로서 함수 내부의의 값은 스택에 저장되는 반면 int
, 클래스의 멤버로 선언 된 in의 값은 선언 된 클래스와 함께 힙에 저장됩니다. 클래스에는 선언 된 클래스와 정확히 동일한 라이프 타입이 있으므로 가비지 수집기의 작업이 거의 필요하지 않습니다. 하지만 더 복잡합니다. @JonSkeet의 책 " C # In Depth "또는 그의 기사 "를 참조하겠습니다.보다 간결한 설명을 위해 .NET의 메모리 "
장점 :
값 유형에는 추가 가비지 콜렉션이 필요하지 않습니다. 그것은 존재하는 인스턴스와 함께 가비지 수집을 가져옵니다. 메서드의 지역 변수는 메서드를 떠날 때 정리됩니다.
단점 :
큰 값 집합이 메서드에 전달되면 수신 변수가 실제로 복사하므로 메모리에 두 개의 중복 값이 있습니다.
수업을 놓치면 모든 oop 혜택이 손실됩니다.
참조 유형 :
값이 아닌 값의 메모리 주소를 보유합니다.
예:
수업
저장:
힙에 저장
장점 :
참조 변수를 메소드에 전달하면 실제로 원래 값이 변경되는 반면 값 유형에서는 주어진 변수의 사본이 취해지고 그 값이 변경됩니다.
변수의 크기가 클 때 참조 형이 좋다
클래스는 참조 유형 변수로 제공되므로 재사용 성을 제공하므로 객체 지향 프로그래밍에 도움이됩니다.
단점 :
값을 읽을 때 할당 및 역 참조시 더 많은 작업 참조 가비지 수집기에 대한 추가 오버로드
컴퓨터가 메모리에 물건을 할당하는 방법을 알고 포인터가 무엇인지 안다면 두 가지의 차이점을 더 쉽게 이해할 수있었습니다.
참조는 일반적으로 포인터와 연관됩니다. 변수가있는 메모리 주소가 실제로 다른 메모리 위치에있는 실제 객체의 다른 메모리 주소 를 보유하고 있음을 의미합니다 .
제가 드리려고하는 예는 지나치게 단순화되어 있으므로 소금 한 알과 함께 가져 가십시오.
컴퓨터 메모리가 내부에 무언가를 담을 수있는 연속 된 사서함 (PO Box 0001에서 PO Box n으로 시작)이라고 상상해보십시오. 사서함이 당신을 위해 그것을하지 않으면 해시 테이블이나 사전 또는 배열 또는 유사한 것을 시도하십시오.
따라서 다음과 같은 작업을 수행 할 때 :
var a = "Hello";
컴퓨터는 다음을 수행합니다.
- 메모리를 할당하고 (예를 들어 메모리 위치 1000에서 5 바이트로 시작) H (1000에서), e (1001에서), l (1002에서), l (1003에서) 및 o (1004에서)를 입력합니다.
- 메모리의 어딘가 (예 : 0500 위치)에 할당하고 변수 a로 할당합니다.
그래서 그것은 일종의 별칭과 같습니다 (0500은 a). - 해당 메모리 위치 (0500)의 값을 1000 (문자열 Hello가 메모리에서 시작하는 위치)에 할당합니다. 따라서 변수 a는 "Hello"문자열의 실제 시작 메모리 위치에 대한 참조 를 보유 합니다.
값 유형은 실제 사물을 메모리 위치에 보관합니다.
따라서 다음과 같은 작업을 수행 할 때 :
var a = 1;
컴퓨터는 다음을 수행합니다.
- 0500에 메모리 위치를 할당하고 변수 a에 할당하십시오 (동일한 별칭)
- 그 안에 값 1을 넣으십시오 (메모리 위치 0500).
실제 값 (1)을 유지하기 위해 추가 메모리를 할당하지 않습니다. 따라서 a는 실제로 실제 값을 보유하고 있기 때문에 값 유형이라고합니다.
This is from a post of mine from a different forum, about two years ago. While the language is vb.net (as opposed to C#), the Value Type vs. Reference type concepts are uniform throughout .net, and the examples still hold.
It is also important to remember that within .net, ALL types technically derive from the base type Object. The value types are designed to behave as such, but in the end they also inherit the functionality of base type Object.
A. Value Types are just that- they represent a distinct area in memory where a discrete VALUE is stored. Value types are of fixed memory size and are stored in the stack, which is a collection of addresses of fixed size.
When you make a statement like such:
Dim A as Integer
DIm B as Integer
A = 3
B = A
You have done the following:
- Created 2 spaces in memory sufficient to hold 32 bit integer values.
- Placed a value of 3 in the memory allocation assigned to A
- Placed a value of 3 in the memory allocation assigned to B by assigning it the same value as the held in A.
The Value of each variable exists discretely in each memory location.
B. Reference Types can be of various sizes. Therefore, they can't be stored in the "Stack" (remember, the stack is a collection of memory allocations of fixed size?). They are stored in the "Managed Heap". Pointers (or "references") to each item on the managed heap are maintained in the stack (Like an Address). Your code uses these pointers in the stack to access objects stored in the managed heap. So when your code uses a reference variable, it is actually using a pointer (or "address" to an memory location in the managed heap).
Say you have created a Class named clsPerson, with a string Property Person.Name
In this case, when you make a statement such as this:
Dim p1 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
Dim p2 As Person
p2 = p1
In the case above, the p1.Name Property will Return "Jim Morrison", as you would expect. The p2.Name property will ALSO return "Jim Morrison", as you would Iintuitively expect. I believe that both p1 and p2 represent distinct addresses on the Stack. However, now that you have assigned p2 the value of p1, both p1 and p2 point to the SAME LOCATION on the managed heap.
Now COnsider THIS situation:
Dim p1 As clsPerson
Dim p2 As clsPerson
p1 = New clsPerson
p1.Name = "Jim Morrison"
p2 = p1
p2.Name = "Janis Joplin"
In this situation, You have created one new instance of the person Class on the Managed Heap with a pointer p1 on the Stack which references the object, and assigned the Name Property of the object instance a value of "Jim Morrison" again. Next, you created another pointer p2 in the Stack, and pointed it at the same address on the managed heap as that referenced by p1 (when you made the assignement p2 = p1).
Here comes the twist. When you the Assign the Name property of p2 the value "Janis Joplin" you are changing the Name property for the object REFERENCED by Both p1 and p2, such that, if you ran the following code:
MsgBox(P1.Name)
'Will return "Janis Joplin"
MsgBox(p2.Name)
'will ALSO return "Janis Joplin"Because both variables (Pointers on the Stack) reference the SAME OBJECT in memory (an Address on the Managed Heap).
Did that make sense?
Last. If you do THIS:
DIm p1 As New clsPerson
Dim p2 As New clsPerson
p1.Name = "Jim Morrison"
p2.Name = "Janis Joplin"
You now have two distinct Person Objects. However, the minute you do THIS again:
p2 = p1
You have now pointed both back to "Jim Morrison". (I am not exactly sure what happened to the Object on the Heap referenced by p2 . . . I THINK it has now gone out of scope. This is one of those areas where hopefullly someone can set me straight . . .). -EDIT: I BELIEVE this is why you would Set p2 = Nothing OR p2 = New clsPerson before making the new assignment.
Once again, if you now do THIS:
p2.Name = "Jimi Hendrix"
MsgBox(p1.Name)
MsgBox(p2.Name)
Both msgBoxes will now return "Jimi Hendrix"
This can be pretty confusing for a bit, and I will say one last time, I may have some of the details wrong.
Good Luck, and hopefully others who know better than me will come along to help clarify some of this . . .
value data type and reference data type
1) value( contain the data directly ) but reference ( refers to the data )
2) in value( every variable has its own copy) but
in reference (more than variable can refer to some objects)
3) in value (operation variable can`t effect on other variable ) but in reference (variable can affect other )
4) value types are(int, bool, float) but reference type are (array , class objects , string )
"Variables that are based on value types directly contain values. Assigning one value type variable to another copies the contained value. This differs from the assignment of reference type variables, which copies a reference to the object but not the object itself." from Microsoft's library.
You can find a more complete answer here and here.
Sometimes explanations won't help especially for the beginners. You can imagine value type as data file and reference type as a shortcut to a file.
So if you copy a reference variable you only copy the link/pointer to a real data somewhere in memory. If you copy a value type, you really clone the data in memory.
This is probably wrong in esoterical ways, but, to make it simple:
Value types are values that are passed normally "by value" (so copying them). Reference types are passed "by reference" (so giving a pointer to the original value). There isn't any guarantee by the .NET ECMA standard of where these "things" are saved. You could build an implementation of .NET that is stackless, or one that is heapless (the second would be very complex, but you probably could, using fibers and many stacks)
Structs are value type (int, bool... are structs, or at least are simulated as...), classes are reference type.
Value types descend from System.ValueType. Reference type descend from System.Object.
Now.. In the end you have Value Type, "referenced objects" and references (in C++ they would be called pointers to objects. In .NET they are opaque. We don't know what they are. From our point of view they are "handles" to the object). These lasts are similar to Value Types (they are passed by copy). So an object is composed by the object (a reference type) and zero or more references to it (that are similar to value types). When there are zero references the GC will probably collect it.
In general (in the "default" implementation of .NET), Value type can go on the stack (if they are local fields) or on the heap (if they are fields of a class, if they are variables in an iterator function, if they are variables referenced by a closure, if they are variable in an async function (using the newer Async CTP)...). Referenced value can only go to the heap. References use the same rules as Value types.
In the cases of Value Type that go on the heap because they are in an iterator function, an async function, or are referenced by a closure, if you watch the compiled file you'll see that the compiler created a class to put these variables, and the class is built when you call the function.
Now, I don't know how to write long things, and I have better things to do in my life. If you want a "precise" "academic" "correct" version, read THIS:
http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx
It's 15 minutes I'm looking for it! It's better than the msdn versions, because it's a condensed "ready to use" article.
The simplest way to think of reference types is to consider them as being "object-IDs"; the only things one can do with an object ID are create one, copy one, inquire or manipulate the type of one, or compare two for equality. An attempt to do anything else with an object-ID will be regarded as shorthand for doing the indicated action with the object referred to by that id.
Suppose I have two variables X and Y of type Car--a reference type. Y happens to hold "object ID #19531". If I say "X=Y", that will cause X to hold "object ID #19531". Note that neither X nor Y holds a car. The car, otherwise known as "object ID #19531", is stored elsewhere. When I copied Y into X, all I did was copy the ID number. Now suppose I say X.Color=Colors.Blue. Such a statement will be regarded as an instruction to go find "object ID#19531" and paint it blue. Note that even though X and Y now refer to a blue car rather than a yellow one, the statement doesn't actually affect X or Y, because both still refer to "object ID #19531", which is still the same car as it always has been.
Variable types and Reference Value are easy to apply and well applied to the domain model, facilitate the development process.
To remove any myth around the amount of "value type", I will comment on how this is handled on the platform. NET, specifically in C # (CSharp) when called APIS and send parameters by value, by reference, in our methods, and functions and how to make the correct treatment of the passages of these values.
Read this article Variable Type Value and Reference in C #
Suppose v
is a value-type expression/variable, and r
is a reference-type expression/variable
x = v
update(v) //x will not change value. x stores the old value of v
x = r
update(r) //x now refers to the updated r. x only stored a link to r,
//and r can change but the link to it doesn't .
So, a value-type variable stores the actual value (5, or "h"). A reference-type varaible only stores a link to a metaphorical box where the value is.
Value Type:
Fixed memory size.
Stored in Stack memory.
Holds actual value.
Ex. int, char, bool, etc...
Reference Type:
Not fixed memory.
Stored in Heap memory.
Holds memory address of actual value.
Ex. string, array, class, etc...
There is not a single difference between value types and reference types, there are many little details that are stated explicitly by the standard and some of them are not easy to understand, especially for beginners.
See ECMA standard 33, Common Language Infrastructure (CLI). The CLI is also standardized by the ISO. I would provide a reference but for ECMA we must download a PDF and that link depends on the version number. ISO standards cost money.
One difference is that value types can be boxed but reference types generally cannot be. There are exceptions but they are quite technical.
Value types cannot have parameter-less instance constructors or finalizers and they cannot refer to themselves. Referring to themselves means for example that if there is a value type Node then a member of Node cannot be a Node. I think there are other requirements/limitations in the specifications but if so then they are not gathered together in one place.
'Programing' 카테고리의 다른 글
$ or 조건이있는 Mongoose의 찾기 방법이 제대로 작동하지 않습니다. (0) | 2020.09.03 |
---|---|
렌더링 중 예외 발생 : 모드 0을 찾을 수 없습니다. (0) | 2020.09.03 |
AND 및 OR 연산자를 사용하여 속성별로 jQuery 선택 (0) | 2020.09.03 |
함수 매개 변수 목록 내의 중괄호는 es6에서 무엇을합니까? (0) | 2020.09.02 |
Mongodb : 사용하기 전에 알아야 할 사항은 무엇입니까? (0) | 2020.09.02 |