문제

검증, 추적 변경 등을 위해 속성의 후원 필드에 액세스 할 수있는 방법이 있습니까?

다음과 같은 것이 가능합니까? 그렇지 않은 경우 .NET 4 / C# 4에 계획이 있습니까?

public string Name
{
    get;
    set
    {
        if (value != <Keyword>)
        {
            RaiseEvent();
        }
        <Keyword> = value;
    }
}

제가 가지고있는 주요 문제는 자동 속성을 사용하면 검증 등의 유연성이 동일한 유연성을 허용하지 않는다는 것입니다. 그러나 명백한 후원 필드는 액세스 할 수있는 다른 클래스와 마찬가지로 속성의 유효성 검사, 추적 변경 등에 액세스하고 재사용 할 때 백업 필드에 액세스 할 때 포함 된 클래스에 포함 된 일부 상황에서는 단점이 있습니다. 외부 적으로 속성.

위의 예에서 백업 필드에 대한 액세스는 속성에 따라 범위를 지정하여 속성 검증, 변경 추적 등의 우회를 방지합니다.

편집하다: <Backing Field>를 <keyword>로 변경했습니다. 값과 유사한 새로운 키워드를 제안합니다. 필드 기존 코드가 많이 사용되고 있다고 확신하지만 잘 할 수 있습니다.

도움이 되었습니까?

해결책

Mehrdad의 답변에서 귀하의 의견을 읽은 후, 나는 당신의 문제를 조금 더 잘 이해한다고 생각합니다.

개발자가 자신이 쓰고있는 수업에서 개인 상태에 액세스 할 수있는 능력에 대해 우려하고, 검증 논리를 우회합니다. 이는 주가 수업에 전혀 포함되어서는 안된다는 것을 암시합니다.

다음 전략을 제안합니다. ValidatedValue를 나타내는 일반 클래스를 작성하십시오. 이 클래스는 후원 값 만 보유하며 Get and Set 메소드를 통해서만 액세스/돌연변이 만 허용합니다. 유효성 검사 로직을 나타내기 위해 대의원이 ValidatedValue로 전달됩니다.

public class ValidatedValue< T >
{
    private T m_val;
    public ValidationFn m_validationFn;

    public delegate bool ValidationFn( T fn );

    public ValidatedValue( ValidationFn validationFn )
    {
        m_validationFn = validationFn;
    }

    public T get()
    {
        return m_val;
    }

    public void set(T v)
    {
        if (m_validationFn(v))
        {
            m_val = v;
        }
    }
}

물론 필요에 따라 더 많은 대의원을 추가 할 수 있습니다 (예 : 사전/사후 변경 알림을 지원).

귀하의 클래스는 이제 귀하의 재산에 대한 후원 상점 대신에 ValidatedValue를 사용합니다.

아래의 예는 100 미만으로 검증 된 정수가있는 클래스 인 MyClass를 보여줍니다. 예외를 던지는 논리는 ValidatedValue가 아닌 MyClass에 있습니다. 이를 통해 MyClass에 포함 된 다른 상태에 의존하는 복잡한 검증 규칙을 수행 할 수 있습니다. Lambda 표기법은 유효성 검사 대의원을 구성하는 데 사용되었습니다. 대신 멤버 함수에 결합 할 수 있습니다.

public partial class MyClass
{
    private ValidatedValue<int> m_foo;

    public MyClass()
    {
        m_foo = new ValidatedValue<int>(
            v => 
            {
                if (v >= 100) RaiseError();
                return true;
            }
        );
    }

    private void RaiseError()
    {
        // Put your logic here....
        throw new NotImplementedException();
    }

    public int Foo
    {
        get { return m_foo.get(); }
        set { m_foo.set(value); }
    }
}

그것이 도움이되기를 바랍니다 - 원래 주제를 다소 벗어나지 만 실제 관심사에 더 인라인이라고 생각합니다. 우리가 한 일은 유효성 검사 논리를 속성에서 빼앗아 데이터에 넣는 것입니다. 이것이 바로 당신이 원하는 곳입니다.

다른 팁

아니요. 백업 필드에 액세스하려면 자동 속성을 사용하지 않고 직접 굴립니다.

나는 나머지 수업이 아니라 부동산에 의해서만 접근 할 수있는 필드를 갖는 것이 좋다는 데 동의합니다. 나는 항상 그것을 사용할 것입니다.

로서 MSDN 상태 :

"C# 3.0 이후에서 자동 구현 된 속성은 속성 액세서에 추가 로직이 필요하지 않을 때 자산 폐지를보다 간결하게 만듭니다. 또한 클라이언트 코드는 다음 예제에 표시된대로 속성을 선언 할 때 개체를 생성 할 수 있습니다. 개인의 익명의 후원 필드를 작성하여 부동산의 Get and Set Accessor를 통해서만 액세스 할 수 있습니다. "

액세서리에 추가 논리가 있으므로 시나리오에서는 자동 구현 속성을 사용하는 것이 적절하지 않습니다.

백킹 필드가 존재하지만 쉽게 참조하는 것을 막기 위해 엉망인 이름이 주어집니다. 아이디어는 당신이 당신이라는 것입니다. 필드를 직접 참조하지 마십시오. 관심을 끌기 위해 리플렉터를 사용하여 코드를 분해하고 필드 이름을 발견 할 수 있지만이 이름을 실제로 휘발성이므로 필드를 직접 사용하지 않으므로 언제든지 코드가 중단 될 수 있습니다.

아니요,하지만 하위 클래스로 할 수 있습니다.

public class Base
{
    public string Name
    {
        get;
        virtual set;
    }
}

public class Subclass : Base
{
    // FIXME Unsure as to the exact syntax.
    public string Name
    {
        override set
        {
            if (value != base.Name)
            {
                RaiseEvent();
            }

            base.Name = value;
        }
    }
}

그렇게한다면 왜 자동 속성을 사용 하는가?!

간단한 속성이 1.0으로 거슬러 올라갑니다. 나는 모든 특별한 경우에 대해 언어에 복잡성을 더하는 것이 의미가 없다고 생각합니다. 일반 상점/검색 모델을 수행하려면 속성이 필요하거나 그 이상이 필요합니다. 후자의 경우, 정상적인 속성이 할 것입니다.

당신은 이것을 할 수 없습니다. 그것이 제가 글을 쓰기 시작한 이유 중 하나입니다 Moxaml 파워 장난감, 자동 속성을 알림 속성으로 변환 할 수있는 기능을 제공합니다.

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