문제

나는 최근에 '정적 초록'방법이 필요한 것으로 보이는 문제에 부딪쳤다. 왜 불가능한 지 알고 있지만이 제한을 어떻게 해결할 수 있습니까?

예를 들어 설명 문자열이있는 추상 클래스가 있습니다. 이 문자열은 모든 인스턴스에 공통적이므로 정적으로 표시되어 있지만이 클래스에서 파생 된 모든 클래스는 자신의 설명 속성을 제공하므로 추상적으로 표시해야합니다.

abstract class AbstractBase
{
    ...
    public static abstract string Description{get;}
    ...
}

물론 컴파일하지 않을 것입니다. 인터페이스를 사용한다고 생각했지만 인터페이스에는 정적 메소드 서명이 포함되어 있지 않을 수 있습니다.

단순히 비 정적이지 않게 만들고 항상 해당 클래스 특정 정보를 얻기 위해 인스턴스를 가져와야합니까?

어떤 아이디어?

도움이 되었습니까?

해결책

정적과 초록을 결합하는 것은 다소 의미가 없습니다. STATIC의 아이디어는 해당 구성원을 사용하기 위해 클래스의 인스턴스를 제시 할 필요가 없다는 것입니다. 그러나 초록을 사용하면 인스턴스가 구체적인 구현을 제공하는 파생 클래스가 될 것으로 기대합니다.

왜 이런 종류의 조합을 원하는지 알 수 있지만 사실은 'this'또는 비 정적 구성원의 구현 사용을 거부하는 것입니다. 즉, 상위 클래스는 추상 또는 '정적 초록'멤버를 호출하는 것 사이의 근본적인 차이가 없지만 파생 클래스의 구현에 제한을 지시합니다 (둘 다 사용할 구현이 필요한 구현이 필요합니다).

다른 팁

당신은 할 수 없습니다.

이를위한 장소는 속성이 있습니다.

예를 들어

[Name("FooClass")]
class Foo
{
}

설명 속성을 현명하게 구현하기 위해 구현을 연기하는 것이 마음에 들지 않으면 간단히 할 수 있습니다.

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description

그리고 클래스를 구현하는 것은 다음과 같은 일을 할 것입니다.

static string classDescription="My Description for this class";
override string  ClassDescription { get { return classDescription; } }

그런 다음 수업은 설명이있는 계약을 따라야하지만 현명하게 수행하기 위해 그들에게 맡기십시오. 객체 지향적 인 방식으로 구현을 지정하는 방법은 없습니다 (잔인하고 연약한 해킹을 제외하고).

그러나 내 마음 에이 설명은 클래스 메타 데이터이므로 다른 사람들이 설명한대로 속성 메커니즘을 사용하는 것이 좋습니다. 반사의 다중 사용에 대해 특히 걱정이된다면, 관심있는 속성을 반영하는 객체를 만들고 유형과 설명 사이에 사전을 저장하십시오. 그것은 반사를 최소화 할 것입니다 (실행 시간 유형 검사를 제외하고는 그다지 나쁘지 않습니다). 사전은 일반적 으로이 정보가 필요한 클래스의 구성원으로 저장 될 수 있으며, 도메인의 클라이언트가 필요한 경우 싱글 톤 또는 컨텍스트 객체를 통해.

정적 인 경우 변수의 인스턴스가 하나 뿐이며 파생 클래스에서 정적 VAR로 달성하려는 작업을 수행 할 수 있다면 상속이 어떻게 의미가 있는지 알 수 없습니다. 개인적으로 나는 당신이 인스턴스 var를 피하려고 멀리 갈 것이라고 생각합니다.

왜 고전적인 방법이 아닌가?

abstract class AbstractBase
{
    protected string _Description = "I am boring abstract default value";
}

class Foo : AbstractBase {

     public Foo() {
       _Description = "I am foo!";
     }
}

인스턴스에서 호출 해야하는 경우 정적이 아닙니다.

인스턴스에서 호출하지 않는다면 다형성이 없다 (즉, childa.description은 언어에 관한 한 chirlb.description과 완전히 관련이 없음).

가능한 해결 방법은 기본 클래스에서 파생 클래스의 싱글 톤을 제네릭의 도움으로 정의하는 것입니다.

import System;

public abstract class AbstractBase<T>
    where T : AbstractBase<T>, new()
{
    private static T _instance = new T();

    public abstract string Description { get; }
    public static string GetDescription()
    {
        return _instance.Description;
    }
}

public class DerivedClass : AbstractBase<DerivedClass>
{
    public override string Description => "This is the derived Class";
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(DerivedClass.GetDescription());
        Console.ReadKey();
    }
}

속임수는 당신에게 말하는 것입니다 AbstractBase<T> 방법에 대한 몇 가지 세부 사항 DerivedClass 구현됩니다 :

  • 그것은 새롭다 where T: new() 따라서 싱글 톤 인스턴스를 만들 수 있습니다
  • 그것은 그 자체로부터 파생된다 where T : AbstractBase<T> 따라서 구현이있을 것임을 알고 있습니다. Description

이 방법 _instance 포함 Description 정적 방법에서 호출 할 수있는 필드 GetDescription(). 이렇게하면 덮어 쓰게됩니다 Description당신의 DerivedClass 그리고 그 가치를 호출 할 수 있습니다 DerivedClass.GetDescription()

"추상"기본 방법을 던질 수 있습니다. Exception, 그러면 개발자 가이 방법을 아이 수업에서 무시하지 않고 호출하려고한다면 "경고"됩니다.

단점은 클래스를 확장 하고이 방법을 사용하지 않을 수 있다는 것입니다. 그런 다음 제공된 다른 답변을 참조하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top