2016-12-19 3 views
2

このロジックを簡略化することは可能ですか、それを行う一般的な方法はありますか? マークされた属性を検索し、属性の種類に従って解析します。 このコードを最適化する方法を提案してください.Productクラスのすべてのデータ型は文字列になります。シリアル化されたデータをdecimal、int、float型のクラスに直接変換するxmlとしてプロダクト入力を取得しています私たちはどの行がエラーを引き起こしたのかわからないxmlにエラーをスローする項目のリストがあります。プロパティをタイプに動的に変換します

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.Text; 
using System.Threading.Tasks; 

namespace TestSolution 
{ 
    public interface ICustomParser 
    { 
     bool Parse(string input); 
    } 

    public class DecimalParserAttribute : Attribute, ICustomParser 
    { 
     public bool Parse(string input) 
     { 
      if (input == null) return false; 

      decimal decimalValue; 

      return decimal.TryParse(input, out decimalValue); 
     } 
    } 

    public class intParserAttribute : Attribute, ICustomParser 
    { 
     public bool Parse(string input) 
     { 
      if (input == null) return false; 

      int intValue; 

      return int.TryParse(input, out intValue); 
     } 
    } 

    public class Product 
    { 
     [DecimalParser] 
     public string Weight { get; set; } 

     [intParser] 
     public string NoOfItems { get; set; } 

     [intParser] 
     public string GRodes { get; set; } 

     [intParser] 
     public string WRodes { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 

      var sb = Validate(new Product() { NoOfItems = "1", GRodes = "4", Weight = "5", WRodes = "23" }); 

      Console.WriteLine(sb); 
      sb = Validate(new Product() { NoOfItems = "1", GRodes = "4w", Weight = "5", WRodes = "23" }); 

      Console.WriteLine(sb); 
      Console.ReadKey(); 
     } 

     private static string Validate(Product product) 
     { 
      var sb = new StringBuilder(); 

      foreach (var property in product.GetType().GetProperties()) 
      { 
       var value = Convert.ToString(property.GetValue(product, null)); 

       var sel = property.GetAttribute<ICustomParser>(); 

       if (sel == null) continue; 

       var parserinstance = (ICustomParser)Activator.CreateInstance(sel.GetType()); 

       if (parserinstance.Parse(value)) continue; 

       sb.AppendLine(string.Format("{0} Has invalid value", property.Name)); 
      } 
      return sb.ToString(); 
     } 
    } 

    public static class Extensions 
    { 
     public static T GetAttribute<T>(this PropertyInfo property) 
     { 
      return (T)property.GetCustomAttributes(false).Where(s => s is T).FirstOrDefault(); 
     } 
    } 
} 
+1

これは、[CodeReview](http://codereview.stackexchange.com)でより適しているかもしれません。 – HimBromBeere

+0

私はあなたの方法が好きです、私はこのapproch tyを知らない – Esperento57

答えて

0

あなたは一種類のみ(Product)を持っている場合、おそらくそれだけの価値はありません - ちょうどすべての凝っせずに明示的に検証コードを記述します。しかし、あなたは(おそらく、実行時にのみ知られている)を検査するために、複数の種類を持っている場合:


それは実際にそれがする必要がありますどのくらいの速依存します。これはどのくらいの頻度で実行されますか?それは周期的である場合には、行うには膨大な量がありません - 主な変更点は、単に直接パーサをキャストに次のようになります。

var parserInstance = (ICustomParser)sel; 

(それはすでに属性タイプです)

クリティカルパスであればロットがありますが、メタプログラミングの領域に入ります。これは基本的に、シリアライザやORMのようなほとんどのツールが実行時リフレクションを減らすためのものです。実行時にILをハッキングすることに慣れていない場合は、「Sigil」(ナゲットで利用可能)のようなツールを見て、間違ってしまうのをやめることをお勧めします(少なくとも:あなたには間違ったことがあります)。基本的には、データ構造を検査してから、 ILを明示的なコードですべて実行していた場合と同じように表示します。

static readonly DecimalParserAttribute _decimal = new DecimalParserAttribute(); 
public static void Validate(Product product) { 
    var sb = new StringBuilder(); 
    if(!_decimal.Parse(product.Weight)) { 
     sb.Append(...); 
    } 
    // ... etc 
    ..., 
} 
関連する問題