2014-10-30 100 views
2

只有某些可接受的特定值的類中有一些特性。然而,數據庫中的相應字段的類型是字符串(nvarchar)。這意味着該字段可能具有不可接受的值,在這種情況下,應該爲實際字段指定預選值而不是讀取的值。將屬性限制爲特定值

(數據庫的架構或內容不能在這一點改變。)

我試圖找出辦法有可分配一個字符串的屬性,但是,如果字符串不是一個的可接受的,將存儲預先選定的值。

基本上可行的一種方法是使用something that works as a string-based enum作爲內部(專用)字段,並且僅暴露(設置爲public)遵循此邏輯的屬性,如下例所示(在此例中,不可接受的值爲被視爲值「真正的」):

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#語法)給出:

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

任何你沒有在這裏使用* actual *枚舉的理由? – 2014-10-30 16:07:18

+1

爲什麼不使用Enum呢? – 2014-10-30 16:08:08

+0

我以爲我在開始時描述過(除非我的大腦太油炸了,而且我錯過了某些明顯的東西):檢查每個字符串對應於哪個枚舉值並在給定字符串不可接受時決定默認值的代碼會必須爲每個財產重複。 – 2014-10-30 16:09:20

回答

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; } 
    } 
} 

A C++ - 風格的宏將在這裏很有用,也許。