자동 구현 속성을 사용하고 있습니다. 다음을 수정하는 가장 빠른 방법은 내 백업 변수를 선언하는 것입니다.
public Point Origin { get; set; }
Origin.X = 10; // fails with CS1612
오류 메시지 : ‘expression’의 반환 값은 변수가 아니므로 수정할 수 없습니다.
중간 표현식의 결과 인 값 유형을 수정하려고했습니다. 값이 유지되지 않으므로 값이 변경되지 않습니다.
이 오류를 해결하려면 표현식 결과를 중간 값으로 저장하거나 중간 표현식에 참조 유형을 사용하십시오.
답변
Point
값 유형 ( struct
) 이기 때문 입니다 .
이로 인해 Origin
속성에 액세스 하면 참조 유형 ( )에서 와 같이 값 자체가 아닌 클래스가 보유한 값 의 사본 에 액세스 class
하므로 X
속성을 설정하면 설정됩니다. 복사본의 속성을 삭제 한 다음 버리고 원래 값은 변경하지 않습니다. 이것은 아마도 의도 한 것이 아니기 때문에 컴파일러가 경고합니다.
X
값만 변경하려면 다음과 같이해야합니다.
Origin = new Point(10, Origin.Y);
답변
지지 변수를 사용하면 도움이되지 않습니다. Point
유형은 값 형식입니다.
전체 Point 값을 Origin 속성에 할당해야합니다.
Origin = new Point(10, Origin.Y);
문제는 Origin 속성에 액세스 할 때 반환되는 get
것은 Origin 속성 자동 생성 필드에 Point 구조의 복사본이라는 것입니다. 따라서 X 필드를 수정하면이 사본은 기본 필드에 영향을 미치지 않습니다. 컴파일러는이를 감지하여이 작업이 완전히 쓸모 없기 때문에 오류를 발생시킵니다.
자신의 백업 변수를 사용하더라도 get
다음과 같습니다.
get { return myOrigin; }
여전히 Point 구조의 복사본을 반환하고 동일한 오류가 발생합니다.
흠 … 당신의 질문을 더 신중하게 읽으면 실제로 클래스 내에서 직접 백업 변수를 수정하는 것을 의미 할 것입니다.
myOrigin.X = 10;
네, 그게 필요할 것입니다.
답변
이제 오류의 원인이 무엇인지 이미 알고 있습니다. 오버로드가있는 생성자가 존재하지 않아 속성을 가져 오는 경우 (이 경우 X
) 객체 이니셜 라이저를 사용하면 장면 뒤의 모든 마술을 수행 할 수 있습니다. 구조체를 불변으로 만들 필요는 없지만 추가 정보를 제공하면됩니다.
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
class MyClass
{
public Point Origin { get; set; }
}
MyClass c = new MyClass();
c.Origin.X = 23; //fails.
//but you could do:
c.Origin = new Point { X = 23, Y = c.Origin.Y }; //though you are invoking default constructor
//instead of
c.Origin = new Point(23, c.Origin.Y); //in case there is no constructor like this.
이것은 배경 뒤에서 발생하기 때문에 가능합니다.
Point tmp = new Point();
tmp.X = 23;
tmp.Y = Origin.Y;
c.Origin = tmp;
이것은 전혀 권장되지 않는 매우 이상한 일처럼 보입니다 . 다른 방법으로 만 나열하십시오. 더 좋은 방법은 구조체를 불변으로 만들고 적절한 생성자를 제공하는 것입니다.
답변
구조체 대 클래스의 장단점을 토론하는 것 외에도 목표를보고 그 관점에서 문제에 접근하는 경향이 있습니다.
즉, 속성 get 및 set 메소드 뒤에 코드를 작성할 필요가 없다면 (예에서와 같이) Origin
속성이 아니라 클래스의 필드로 간단히 선언하는 것이 쉽지 않을까요? 나는 이것이 당신이 당신의 목표를 달성 할 수 있다고 생각해야합니다.
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
class MyClass
{
public Point Origin;
}
MyClass c = new MyClass();
c.Origin.X = 23; // No error. Sets X just fine
답변
문제는 스택에있는 값을 가리키고 값이 orignal 속성으로 다시 영향을 미치지 않으므로 C #에서는 값 형식에 대한 참조를 반환 할 수 없다는 것입니다. Origin 속성을 제거 하여이 문제를 해결할 수 있다고 생각하고 대신 공용 파일을 사용하십시오. 예, 좋은 해결책이 아니라는 것을 알고 있습니다. 다른 해결책은 Point를 사용하지 않고 대신 자신 만의 Point 유형을 객체로 생성하는 것입니다.
답변
여기서 잡는 것은 객체 자체를 할당하는 것이 아니라 명령문에서 객체의 하위 값을 할당하려고한다는 것입니다. 이 경우 속성 유형이 Point이므로 전체 Point 객체를 할당해야합니다.
Point newOrigin = new Point(10, 10);
Origin = newOrigin;
내가 이해가 되길 바래
답변
다음과 같이 “get set”속성을 제거하면 모든 것이 항상 작동합니다.
기본 유형이 겹친 경우 get; set; …을 사용하십시오.
using Microsoft.Xna.Framework;
using System;
namespace DL
{
[Serializable()]
public class CameraProperty
{
#region [READONLY PROPERTIES]
public static readonly string CameraPropertyVersion = "v1.00";
#endregion [READONLY PROPERTIES]
/// <summary>
/// CONSTRUCTOR
/// </summary>
public CameraProperty() {
// INIT
Scrolling = 0f;
CameraPos = new Vector2(0f, 0f);
}
#region [PROPERTIES]
/// <summary>
/// Scrolling
/// </summary>
public float Scrolling { get; set; }
/// <summary>
/// Position of the camera
/// </summary>
public Vector2 CameraPos;
// instead of: public Vector2 CameraPos { get; set; }
#endregion [PROPERTIES]
}
}
