를 정의하는 추상 클래스가 get
있지만.이 아닌 set
추상 클래스에 관한 한 get
.
public abstract BaseClass
{
public abstract double MyPop
{get;}
}
그러나 일부 파생 클래스에서는 set
속성이 필요하므로이 구현을 살펴보고 있습니다.
public class DClass: BaseClass
{
public override double MyPop
{get;set;}
}
문제는 컴파일 오류가 발생하여
* .set : *. 재정의 할 수있는 set 접근자가 없습니다.
위의 구문이 완벽하게 합법적이라고 생각하지만.
이것에 대한 아이디어가 있습니까? 해결 방법 또는 그 이유는 무엇입니까?
편집 : 내가 생각할 수있는 유일한 접근 방식 은 추상 클래스에서 get
와 set
같이 둘 다 넣고 하위 클래스가 NotImplementedException
if set
가 호출되고 필요하지 않게하는 것입니다. 그것은 특별한 setter 메서드 와 함께 내가 좋아하지 않는 것 입니다.
답변
C # 6.0의 새로운 기능 :
생성자 내에서 setter 만 호출하는 경우 읽기 전용 속성을 사용하여이 문제를 해결할 수 있습니다.
void Main()
{
BaseClass demo = new DClass(3.6);
}
public abstract class BaseClass
{
public abstract double MyPop{ get; }
}
public class DClass : BaseClass
{
public override double MyPop { get; }
public DClass(double myPop) { MyPop = myPop;}
}
답변
한 가지 가능한 대답은 getter를 재정의 한 다음 별도의 setter 메서드를 구현하는 것입니다. 속성 setter가 기본에 정의되지 않도록하려면 다른 옵션이 많지 않습니다.
public override double MyPop
{
get { return _myPop; }
}
public void SetMyPop(double value)
{
_myPop = value;
}
답변
당신이 원하는 것을 할 수 없습니다. 추상 속성에서 setter를 정의해야합니다. 그렇지 않으면 올바르게 재정의 할 수 없습니다.
getter가 정의되고 getter / setter가 구현되는 위치를 아는 유일한 경우는 인터페이스를 사용하는 것입니다.
public interface IBaseInterface
{
double MyPop { get; }
}
public class DClass : IBaseInterface
{
public double MyPop { get; set; }
}
답변
경우 BaseClass
자신의 코드베이스에, 당신은 할 수 있습니다 :
abstract public class BaseClass
{
abstract public double MyPop { get; protected set; }
}
public class DClass : BaseClass
{
private double _myProp;
public override double MyProp
{
get { return _myProp; }
protected set { _myProp = value; }
}
}
편집 : 그런 다음 DClass 등에서 공용 메서드를 만들 수 있습니다 SetMyProp(double myProp)
. 도메인 모델에 대한 클래스 디자인은 기본 클래스에서 직접 속성을 설정할 수없는 이유와 파생 클래스에서 설정할 수있는 이유에 대해 명확하게 설명해야합니다.
답변
하려는 일을하는 것이 방법을 찾았다면 좋은 디자인이 될 것이라고 확신하십니까?
하위 클래스의 개체가 부모 클래스의 개체가 만들 수없는 상태 변경을 수행 할 수 있습니다. Liskov 대체 원칙을 위반하지 않습니까?
답변
다음과 같이 할 수 있습니다.
abstract class TestBase
{
public abstract int Int { get; }
}
class TestDerivedHelper : TestBase
{
private int _Int;
public override int Int
{
get
{
return _Int;
}
}
protected void SetInt(int value)
{
this._Int = value;
}
}
class TestDerived : TestDerivedHelper
{
public new int Int
{
get { return base.Int; }
set { base.SetInt(value); }
}
}
TestDerived를 사용하면 원하는 기능이 제공됩니다. 이 메서드에서 볼 수있는 유일한 단점은 TestDerivedHelper에서 모든 추상 메서드를 구현해야하지만 나중에 더 많은 제어를 제공한다는 것입니다.
도움이 되었기를 바랍니다. 😉
답변
이것이 불가능한 이유는 매개 변수가 C #에 의해 존재하도록 “매그 킹”되는 방식 때문입니다. 매개 변수를 정의 할 때 C #은 암시 적 getter 및 setter가 조작 하는 개인 필드를 만듭니다 . 기본 클래스에 setter가 없으면 하위 클래스에 작성된 메서드에서이 변수를 변경할 수 없습니다 (개인 플래그가 하위 클래스도 액세스하지 못하도록 금지하므로). 일반적으로 발생하는 것은 대신 기본 클래스의 암시 적 setter를 사용하는 것입니다.
모든 하위 클래스가이를 수행 할 수없는 경우 기본 클래스에 세트를 넣는 것은 권장하지 않습니다. 이는 다형성 프로그래밍의 전체 원칙에 위배되기 때문입니다 (추상 클래스에 정의 된 모든 추상 메서드는 하위 클래스에 의해 구현되어야 함). 다른 답변에서 설명한 것처럼 특별한 setter 메서드를 만드는 것이 가장 좋은 방법 일 것입니다.
