programing

Get 무시하지만 설정되지 않음

nasanasas 2020. 10. 22. 08:07
반응형

Get 무시하지만 설정되지 않음


를 정의하는 추상 클래스가 get있지만, 그렇지 않습니다 set. 그 추상 클래스에 관한 한 get.

public abstract BaseClass
{
  public abstract double MyPop
  {get;}
}

그러나 일부 파생 클래스에서는 set속성이 필요하므로이 구현을 살펴보고 있습니다.

public class DClass: BaseClass
{
  public override double MyPop
  {get;set;}
}

문제는 컴파일 오류가 발생하여

* .set : *. 재정의 할 수있는 set 접근자가 없습니다.

위의 구문이 완벽하게 합법적이라고 생각하지만.

이것에 대한 아이디어가 있습니까? 해결 방법 또는 그 이유는 무엇입니까?

편집 : 내가 생각할 수있는 유일한 접근 방식 은 추상 클래스에서 getset같이 둘 다 넣고 하위 클래스가 NotImplementedExceptionif 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 메서드를 만드는 것이 가장 좋은 방법 일 것입니다.


포위

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에서 모든 추상 메서드를 구현해야하지만 나중에 더 많은 제어를 제공한다는 것입니다.

저는이 접근 방식을 사용하고 저에게 매우 잘 작동합니다. 또한 "TestDerivedHelper"클래스도 추상화 한 다음 모든 메서드를 "TestDerived"클래스에서 구현해야합니다.


Even though this thread is old I'm positing my solution, in case it helps someone. It is not my own but is based off answers in other SO topics.

public abstract BaseClass
{
  public double MyPoP { get { return GetMyPoP; } }

  protected abstract double GetMyPoP { get; }
}

public class DClass: BaseClass
{
  public new double MyPoP { get; set; }

  protected override double GetMyPop { get { return MyPoP; } }
}

This solution adds an extra line of code for each such property that needs accessor modified. However, there is no change to external visibility and provides needed functionality.


public abstract class BaseClass
{
    public abstract double MyPop { get; }
}

public class DClass: BaseClass
{
    private double _myPop = 0;
    public override double MyPop 
    {
        get { return _myPop; }
    }

    // some other methods here that use the _myPop field
}

If you need to set the property from outside DClass then maybe it would be better to put the setter into the base class.


EDIT:

OK I may have been hasty with this response, but I've given it some more thought now.

Do you have to use an abstract base class? If it's not required, try this:

public interface ISomeRelevantName
{
    double MyPop { get; }
}

public class DClass : ISomeRelevantName
{
    public double MyPop { get; set; }
}

Why not just have a property in the base class that has a private setter, then in your subclass that needs the setter, override it and make it public.


You cannot override the set accessor since the base class has no set accessor defined.

What you can do is use the new keyword to hide the base classes implementation, but that may not be what you want.

참고URL : https://stackoverflow.com/questions/2026546/override-get-but-not-set

반응형