2014-10-30 4 views
2

허용 가능한 특정 값만있는 클래스의 일부 속성이 있습니다. 그러나 데이터베이스의 해당 필드는 string 유형입니다 (nvarchar). 이것은 필드가 받아 들일 수없는 값을 가질 가능성이 있음을 의미합니다. 실제 필드는 읽은 값 대신 미리 선택된 값을 할당해야합니다.속성을 특정 값으로 제한

(데이터베이스의 스키마 나 내용이 시점에서 변경 될 수 없습니다.)

해당 문자열이 하나가 아닌 경우 나, 문자열을 할당 할 수있는 속성을 가질 수있는 방법을 알아 내려고하지만 해요 수용 가능한 것들 중에서 미리 선택된 값을 저장할 것입니다.

기본적으로 작동하는 한 가지 접근 방식은 내부 (개인) 필드로 something that works as a string-based enum을 사용하고 다음 예와 같이이 논리를 따르는 속성 만 공개 (공개로 설정)합니다 (이 경우 허용되지 않는 값은

public class Item 
{ 
    private sealed class Reality 
    { 
     public readonly string Value; 

     private Reality(string value) 
     { 
      Value = value; 
     } 

     public static readonly Reality Real = new Reality("Real"); 
     public static readonly Reality Imaginary = new Reality("Imaginary"); 
     public static readonly Reality BasedOnReality = new Reality("Based on reality"); 
    } 

    private Reality _realityValue; 

    public string RealityStr 
    { 
     get { return _realityValue.Value; } 
     set 
     { 
      if (value == Reality.Imaginary.Value) 
      { 
       _realityValue = Reality.Imaginary; 
      } 
      else if (value == Reality.BasedOnReality.Value) 
      { 
       _realityValue = Reality.BasedOnReality; 
      } 
      else 
      { 
       _realityValue = Reality.Real; 
      } 
     } 
    } 
} 

위 올바르게 작동합니다 :) "진짜"값으로 치료를 받고

Item item = new Item(); 

item.RealityStr = "Real"; 
Console.WriteLine(item.RealityStr); //Output: Real 

item.RealityStr = "Imaginary"; 
Console.WriteLine(item.RealityStr); //Output: Imaginary 

item.RealityStr = "Existing"; 
Console.WriteLine(item.RealityStr); //Output: Real 

이 방법의 문제는 이러한 클래스와 해당 세터가 정의되어야 할 것입니다 각 필드에 대해 별도로 이상적으로는 논리 번만 정의 될 것이며, 가능한 값의리스트 필드의 정의는 아래와 같이 (유효하지 C# 1 구)에 주어질 것이다 :

public class Item 
{ 
    public LimitedString<"Real", "Imaginary", "Based on reality"> Reality; 

    public LimitedString<"Other", "Blue", "Red", "Green"> Colour; 
} 

(이 예에서는 LimitedString이 유형은 그 문자열의 주어진 목록에 대해 내가 찾고있는 논리를 구현합니다. 기본값은 첫 번째 것입니다.)

문자열 목록이있는 사용자 지정 특성을 사용하여이 작업을 수행 할 수 있습니다. 구문은 다음과 같습니다. 특수 클래스.

public class Item 
{ 
    [AcceptableValues("Real", "Imaginary", "Based on reality")] 
    public LimitedString Reality; 

    [AcceptableValues("Other", "Blue", "Red", "Green")] 
    public LimitedString Colour; 
} 

그러나 클래스가 자체의 특정 인스턴스에 적용되는 특성을 읽을 수있는 방법을 찾을 수 없었습니다. 다시 말해 일부 논리가 수용 가능한 값을 갖는 각 속성에 대해 복제되어야한다는 것을 의미합니다.
또한 할당 연산자를 오버로드 할 수 없기 때문에 함수에 의해 할당이 수행되어야하고 public implicit operator LimitedString(string value)을 사용하면 새 LimitedString 객체를 반환하므로 각 속성마다 다른 클래스가 다시 필요합니다.

각 특정 필드/속성에 대해 논리를 복제하지 않고 C#에서 수행 할 수 있습니까? 문제를 잘 설명했으면 좋겠어요.

+4

* 실제 * 열거 형을 사용하지 않는 이유는 무엇입니까? –

+1

대신 열거 형을 사용하지 않는 이유는 무엇입니까? –

+0

나는 처음에 그걸 설명했다고 생각했다. (뇌가 너무 튀지 않고 뭔가 명확하지 않다면) : 각 문자열이 열거 형 값을 검사하고 주어진 문자열이 받아 들여지지 않는 경우 기본값을 결정하는 코드 각 속성에 대해 복제해야합니다. –

답변

1

내가 상상했던 것처럼 한 줄로 처리 할 수 ​​없다고 생각합니다. 내가 생각하는 다음과 갈거야

코드의 최소한의 중복 함께 할 수있는 방법입니다

public class Item 
{ 
    private readonly LimitedString _reality = new LimitedString("Real", "Imaginary", "Based on reality"); 
    public string Reality 
    { 
     get { return _reality.Value; } 
     set { _reality.Value = value; } 
    } 

    private readonly LimitedString _colour = new LimitedString("Other", "Blue", "Red", "Green"); 
    public string Colour 
    { 
     get { return _colour.Value; } 
     set { _colour.Value = value; } 
    } 
} 

C++ - 스타일 매크로 어쩌면, 여기에 유용 할 것이다.