있을 수있다
TL; DR - 당신이 원한다면 당신은 세터와 GET-유일한 방법을 재정의 할 수 있습니다. 기본적으로는 다음과 같습니다.
같은 이름을 사용하여 new
a get
와 a set
를 모두 가진 속성을 만듭니다 .
다른 작업을 수행하지 않으면 get
파생 클래스가 기본 유형을 통해 호출 될 때 이전 메소드가 계속 호출됩니다. 이 문제를 해결하려면 이전 메소드에서 abstract
사용 하는 중간 계층을 추가 하여 새 메소드의 결과 를 강제로 리턴하십시오 .override
get
get
이를 통해 기본 정의에 속성 이없는 경우에도 get
/로 속성을 재정의 할 수 있습니다 set
.
보너스로 원하는 경우 반환 유형을 변경할 수도 있습니다.
기본 정의가 get
-only 인 경우 더 파생 된 리턴 유형을 사용할 수 있습니다.
기본 정의가 set
-only 인 경우 덜 파생 된 반환 유형을 사용할 수 있습니다.
기본 정의가 이미 get
/ set
이면 다음을 수행하십시오.
모든 경우에 원하는 경우 동일한 반환 유형을 유지할 수 있습니다. 아래 예제는 단순화를 위해 동일한 리턴 유형을 사용합니다.
상황 : 기존 get
전용 속성
수정할 수없는 클래스 구조가 있습니다. 아마도 하나의 클래스 일 수도 있고 기존 상속 트리 일 수도 있습니다. 어떤 경우이든 set
속성에 메서드를 추가하려고 하지만 할 수는 없습니다.
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
문제 : 할 수 없습니다 - 단지와 /override
get
get
set
당신이 원하는 override
A를 get
/ set
부동산,하지만 컴파일되지 않습니다.
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
솔루션 : abstract
중간 레이어 사용
당신이 할 수있는 직접적 동안 override
A를 get
/ set
재산, 당신은 할 수 있습니다 :
같은 이름 으로 new
get
/ set
속성을 만듭니다 .
override
이전 get
새에 대한 접근과 방법 get
방법은 일관성을 보장합니다.
따라서 먼저 abstract
중간 계층 을 작성하십시오 .
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
그런 다음 이전에 컴파일하지 않은 클래스를 작성하십시오. 실제로 override
는 get
-only 속성을 사용 하지 않기 때문에 이번에는 컴파일 됩니다. 대신 new
키워드를 사용하여 교체하고 있습니다.
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
결과 : 모든 것이 작동합니다!
분명히 이것은 의도 한대로 작동합니다 D
.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
D
기본 클래스 중 하나로 볼 때 모든 것이 여전히 의도 한대로 작동합니다 ( 예 : A
또는) B
. 그러나 그것이 작동하는 이유는 조금 덜 분명 할 수 있습니다.
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
그러나의 기본 클래스 정의 get
는 여전히 파생 클래스의 정의에 의해 재정의 get
되므로 여전히 완전히 일관성이 있습니다.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
토론
이 방법을 사용하면 속성 set
을 get
전용 속성 에 추가 할 수 있습니다 . 그것을 사용하여 다음과 같은 작업을 수행 할 수도 있습니다.
에 어떤 속성을 변경 get
- 단지, set
오닐, 또는 get
- 및 - set
관계없이 기본 클래스에 무엇의 속성입니다.
파생 클래스에서 메소드의 리턴 유형을 변경하십시오.
주요 단점은 더 많은 코딩이 있고 abstract class
상속 트리에 추가가 있다는 것 입니다. 매개 변수를 사용하는 생성자는 중간 계층에서 복사 / 붙여 넣기해야하기 때문에 약간 성 가실 수 있습니다.