最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ASP.Net Core中使用枚舉類(lèi)而不是枚舉的方法

 更新時(shí)間:2019年06月03日 09:10:20   作者:菠蘿吹雪—Code  
這篇文章主要給大家介紹了關(guān)于ASP.Net Core中使用枚舉類(lèi)而不是枚舉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用ASP.Net Core具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言:

我相信大家在編寫(xiě)代碼時(shí)經(jīng)常會(huì)遇到各種狀態(tài)值,而且為了避免硬編碼和代碼中出現(xiàn)魔法數(shù),通常我們都會(huì)定義一個(gè)枚舉,來(lái)表示各種狀態(tài)值,直到我看到Java中這樣使用枚舉,我再想C# 中可不可以這樣寫(xiě),今天就分享一下我的感悟。

一、通常我們是這樣使用枚舉的

(1)switch中使用枚舉

 public enum EmployeeType
 {
 Manager,
 Servant,
 AssistantToTheRegionalManager
 }
public class Employee
 {
 public EmployeeType Type { get; set; }
 public decimal Bonus { get; set; }
 }
static void ProcessBonus(Employee employee)
 {
  switch (employee.Type)
  {
  case EmployeeType.Manager:
   employee.Bonus = 1000m;
   break;
  case EmployeeType.Servant:
   employee.Bonus = 0.01m;
   break;
  case EmployeeType.AssistantToTheRegionalManager:
   employee.Bonus = 1.0m;
   break;
  default:
   throw new ArgumentOutOfRangeException();
  }
 }

在沒(méi)有進(jìn)某唐時(shí)我也是這樣的寫(xiě)的,代碼很爛,違法了開(kāi)閉原則,擴(kuò)展性極差。在代碼規(guī)范中是不允許出現(xiàn)這樣的寫(xiě)法的。對(duì)于上面的寫(xiě)法可以使用設(shè)計(jì)模式來(lái)重構(gòu)。后面會(huì)繼續(xù)更新設(shè)計(jì)模式的文章。

(2)類(lèi)型轉(zhuǎn)換

EnumTricks.IsVolumeHigh((Volume)27);
EnumTricks.High((int)Medium);

二、枚舉的不好之處

關(guān)于枚舉的MSDN文檔說(shuō)了什么:

“The enum keyword is used to declare an enumeration, a distinct type that consists of a set of named constants called the enumerator list. Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of the enumeration elements is int. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1.

(1)沒(méi)有類(lèi)型安全

枚舉是簡(jiǎn)單的值類(lèi)型,可以提供對(duì)無(wú)效值的保護(hù),并且不會(huì)出現(xiàn)任何行為。他們是有用的,因?yàn)樗麄兪悄Х〝?shù)字的改進(jìn),但就是這樣。如果要約束類(lèi)型可能的值,枚舉不一定能幫助您,因?yàn)槿匀豢梢蕴峁o(wú)效類(lèi)型。例如,此枚舉有三個(gè)值,默認(rèn)情況下將具有int類(lèi)型。值范圍為1到3。

 public enum Volume
 {
 Low = 1,
 Medium,
 High
 }
public static class EnumTricks
 {
 public static bool IsVolumeHigh(Volume volume)
 {
  var result = false;

  switch (volume)
  {
  case Volume.Low:
   Console.WriteLine("Volume is low.");
   break;

  case Volume.Medium:
   Console.WriteLine("Volume is medium.");
   break;

  case Volume.High:
   Console.WriteLine("Volume is high.");
   result = true;
   break;
  }

  return result;
 }
 }
static void Main(string[] args)
 {
  EnumTricks.IsVolumeHigh((Volume)27);



  Console.ReadKey();
 }
public static class EnumTricks
 {
 public static bool IsVolumeHigh(Volume volume)
 {
  var result = false;

  switch (volume)
  {
  case Volume.Low:
   Console.WriteLine("Volume is low.");
   break;

  case Volume.Medium:
   Console.WriteLine("Volume is medium.");
   break;

  case Volume.High:
   Console.WriteLine("Volume is high.");
   result = true;
   break;
  }

  return result;
 }

 public static int EnumToInt(Volume volume)
 {
  return (int)volume;
 }

 public static Volume IntToEnum(int intValue)
 {
  return (Volume)intValue;
 }

 public static Volume StringToEnum(string stringValue)
 {
  return (Volume)Enum.Parse(typeof(Volume), stringValue);
 }

 public static int StringToInt(string stringValue)
 {
  var volume = StringToEnum(stringValue);
  return EnumToInt(volume);
 }
 public static string EnumToString(Volume volume)
 {
  return volume.ToString();
 }
 }

這應(yīng)該失敗,至少在運(yùn)行時(shí)。它沒(méi)有。這真的很奇怪......在編譯期間或運(yùn)行期間都不會(huì)檢測(cè)到錯(cuò)誤的調(diào)用。你會(huì)覺(jué)得自己處于一個(gè)虛假的安全狀態(tài)。如果,我們把傳進(jìn)去的枚舉轉(zhuǎn)換為string時(shí),來(lái)看看這兩種情況有什么不同:

我不知道大家平時(shí)在使用枚舉的時(shí)候,是否有意識(shí)檢查傳入的是否是有效的值??梢允褂?code>Enum.IsDefined()來(lái)檢查int值是否是一個(gè)有效的值

解決方案:如果int值在枚舉值的定義范圍內(nèi),則使用Enum.IsDefined()查找。如果在范圍內(nèi),則返回True,否則返回False。

(2)轉(zhuǎn)化

您是否嘗試過(guò)將enum轉(zhuǎn)換為int,int轉(zhuǎn)換為enum,string轉(zhuǎn)換為enum,將字符串轉(zhuǎn)換為enum的int值?如下代碼:

public static class EnumTricks
 {
  public static bool IsVolumeHigh(Volume volume)
  {
   var result = false;

   switch (volume)
   {
    case Volume.Low:
     Console.WriteLine("Volume is low.");
     break;

    case Volume.Medium:
     Console.WriteLine("Volume is medium.");
     break;

    case Volume.High:
     Console.WriteLine("Volume is high.");
     result = true;
     break;
   }

   return result;
  }

  public static int EnumToInt(Volume volume)
  {
   return (int)volume;
  }

  public static Volume IntToEnum(int intValue)
  {
   return (Volume)intValue;
  }

  public static Volume StringToEnum(string stringValue)
  {
   return (Volume)Enum.Parse(typeof(Volume), stringValue);
  }

  public static int StringToInt(string stringValue)
  {
   var volume = StringToEnum(stringValue);
   return EnumToInt(volume);
  }
 }

是不是我們?nèi)粘5拇a中也有這樣的類(lèi)型轉(zhuǎn)換代碼,不是說(shuō)不好,只是類(lèi)型轉(zhuǎn)換也是有性能損失的,如果能換中方式可以同樣實(shí)現(xiàn)而且還避免以上問(wèn)題豈不是更好,這樣我們的代碼也更好維護(hù)和擴(kuò)展,下面我們通過(guò)使用枚舉類(lèi)的方式來(lái)解決這個(gè)問(wèn)題。

三、使用枚舉類(lèi)而不是枚舉類(lèi)型

public class Enumeration: IComparable
 {
  private readonly int _value;
  private readonly string _displayName;

  protected Enumeration()
  {
  }

  protected Enumeration(int value, string displayName)
  {
   _value = value;
   _displayName = displayName;
  }

  public int Value
  {
   get { return _value; }
  }

  public string DisplayName
  {
   get { return _displayName; }
  }

  public override string ToString()
  {
   return DisplayName;
  }

  public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
  {
   var type = typeof(T);
   var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

   foreach (var info in fields)
   {
    var instance = new T();
    var locatedValue = info.GetValue(instance) as T;

    if (locatedValue != null)
    {
     yield return locatedValue;
    }
   }
  }

  public override bool Equals(object obj)
  {
   var otherValue = obj as Enumeration;

   if (otherValue == null)
   {
    return false;
   }

   var typeMatches = GetType().Equals(obj.GetType());
   var valueMatches = _value.Equals(otherValue.Value);

   return typeMatches && valueMatches;
  }

  public override int GetHashCode()
  {
   return _value.GetHashCode();
  }

  public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
  {
   var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
   return absoluteDifference;
  }

  public static T FromValue<T>(int value) where T : Enumeration, new()
  {
   var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
   return matchingItem;
  }

  public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
  {
   var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
   return matchingItem;
  }

  private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
  {
   var matchingItem = GetAll<T>().FirstOrDefault(predicate);

   if (matchingItem == null)
   {
    var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
    throw new ApplicationException(message);
   }

   return matchingItem;
  }

  public int CompareTo(object other)
  {
   return Value.CompareTo(((Enumeration)other).Value);
  }
 }
public class Volume: Enumeration
 {
  private Volume() { throw new Exception(""); }
  private Volume(int value, string displayName): base(value, displayName) { }


  public static readonly Volume Low = new Volume(1, nameof(Low).ToLowerInvariant());
  public static readonly Volume Medium = new Volume(2, nameof(Medium).ToLowerInvariant());
  public static readonly Volume High = new Volume(3, nameof(High).ToLowerInvariant());


  public static IEnumerable<Volume> List() =>
   new[] { Low, Medium, High };

  public static Volume From(int value)
  {
   var state = List().SingleOrDefault(s => s.Value == value);

   if (state == null)
   {
    throw new Exception($"Possible values for Volume: {String.Join(",", List().Select(s => s.Value))}");
   }

   return state;
  }

  public static Volume FromName(string name)
  {
   var state = List()
    .SingleOrDefault(s => String.Equals(s.DisplayName, name, StringComparison.CurrentCultureIgnoreCase));

   if (state == null)
   {
    throw new Exception($"Possible values for Volume: {String.Join(",", List().Select(s => s.DisplayName))}");
   }

   return state;
  }
 }
static void Main(string[] args)
  {
   //EnumTricks.IsVolumeHigh((Volume)27);

   //var tmp = Enum.IsDefined(typeof(Volume), 3);
   //var str = EnumTricks.EnumToString((Volume)27);
   //var str2 = EnumTricks.EnumToString((Volume)3);


   //Console.WriteLine($"Volume 27:{str}");
   //Console.WriteLine($"Volume 3:{str2}");

   Console.WriteLine("------------------------------------------------------------");
   
   Console.WriteLine(Volume.High.Value);
   Console.WriteLine(Volume.High.DisplayName);

   var volume = Volume.From(2);
   var volume2 = Volume.FromName("high");
   var none = Volume.From(27);

   Console.ReadKey();
  }

四、應(yīng)用

代碼如下:

Error文件下:

public interface ICommonError
 {
  int GetErrCode();
  string GetErrMsg();
  ICommonError SetErrMsg(string errMsg);
 }
public class Enumeration : IComparable
 {
  private readonly int _value;
  private readonly string _displayName;

  protected Enumeration()
  {
  }

  protected Enumeration(int value, string displayName)
  {
   _value = value;
   _displayName = displayName;
  }

  public int Value
  {
   get { return _value; }
  }

  public string DisplayName
  {
   get { return _displayName; }
  }

  public override string ToString()
  {
   return DisplayName;
  }

  public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
  {
   var type = typeof(T);
   var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

   foreach (var info in fields)
   {
    var instance = new T();
    var locatedValue = info.GetValue(instance) as T;

    if (locatedValue != null)
    {
     yield return locatedValue;
    }
   }
  }

  public override bool Equals(object obj)
  {
   var otherValue = obj as Enumeration;

   if (otherValue == null)
   {
    return false;
   }

   var typeMatches = GetType().Equals(obj.GetType());
   var valueMatches = _value.Equals(otherValue.Value);

   return typeMatches && valueMatches;
  }

  public override int GetHashCode()
  {
   return _value.GetHashCode();
  }

  public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
  {
   var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
   return absoluteDifference;
  }

  public static T FromValue<T>(int value) where T : Enumeration, new()
  {
   var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
   return matchingItem;
  }

  public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
  {
   var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
   return matchingItem;
  }

  private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
  {
   var matchingItem = GetAll<T>().FirstOrDefault(predicate);

   if (matchingItem == null)
   {
    var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
    throw new ApplicationException(message);
   }

   return matchingItem;
  }

  public int CompareTo(object other)
  {
   return Value.CompareTo(((Enumeration)other).Value);
  }
 }
public class EmBusinessError : Enumeration, ICommonError
 {
  private int errCode;
  private String errMsg;

  public static readonly EmBusinessError parameterValidationError = new EmBusinessError(10001, "參數(shù)不合法");

  private EmBusinessError() { throw new Exception("私有構(gòu)造函數(shù)不能調(diào)用"); }
  private EmBusinessError(int value, string displayName) : base(value, displayName) {

   this.errCode = value;
   this.errMsg = displayName;
  }
  
  public int GetErrCode()
  {
   return this.errCode;
  }

  public string GetErrMsg()
  {
   return this.errMsg;
  }

  public void SetErrCode(int errCode)
  {
   this.errCode = errCode;
  }

  public ICommonError SetErrMsg(string errMsg)
  {
   this.errMsg = errMsg;

   return this;
  }
 }
//包裝器業(yè)務(wù)異常類(lèi)實(shí)現(xiàn)
 public class BusinessException : Exception, ICommonError
 {
  private ICommonError commonError;

  //直接接收EmBusinessError的傳參用于構(gòu)造業(yè)務(wù)異常
  public BusinessException(ICommonError commonError):base()
  {
   this.commonError = commonError;
  }
  public BusinessException(ICommonError commonError, string errMsg):base()
  {
   this.commonError = commonError;
   this.commonError.SetErrMsg(errMsg);
  }
  public int GetErrCode()
  {
   return this.commonError.GetErrCode();
  }

  public string GetErrMsg()
  {
   return this.commonError.GetErrMsg();
  }

  public ICommonError SetErrMsg(string errMsg)
  {
   this.commonError.SetErrMsg(errMsg);

   return this;
  }
  public ICommonError GetCommonError()
  {
   return commonError;
  }
 }

異常中間件:

public class ExceptionHandlerMiddleWare
 {
  private readonly RequestDelegate next;
  
  /// <summary>
  /// 
  /// </summary>
  /// <param name="next"></param>
  public ExceptionHandlerMiddleWare(RequestDelegate next)
  {
   this.next = next;
  }

  public async Task Invoke(HttpContext context)
  {
   try
   {
    await next(context);
   }
   catch (Exception ex)
   {
    await HandleExceptionAsync(context, ex);
   }
  }

  private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
  {
   if (exception == null) return;
   await WriteExceptionAsync(context, exception).ConfigureAwait(false);
  }

  private static async Task WriteExceptionAsync(HttpContext context, Exception exception)
  {
   var response = context.Response;
   response.ContentType = "application/json;charset=utf-8";
   var result = new CommonReturnType();
   

   if (exception is BusinessException)
   {
    var businessException = (BusinessException)exception;

    var errModel = new { errCode= businessException.GetErrCode(), errMsg= businessException.GetErrMsg() };

    result = CommonReturnType.Create(errModel, "fail");

    
   }
   

   await response.WriteAsync(JsonConvert.SerializeObject(new { data = result.GetData(), status = result.GetStatus() }) ).ConfigureAwait(false);
  }

 }

Response文件夾:

public class CommonReturnType
 {
  //表明對(duì)應(yīng)請(qǐng)求的返回處理結(jié)果 "success" 或 "fail"
  private string status;

  //若status=success,則data內(nèi)返回前端需要的json數(shù)據(jù)
  //若status=fail,則data內(nèi)使用通用的錯(cuò)誤碼格式
  private object data;

  //定義一個(gè)通用的創(chuàng)建方法
  public static CommonReturnType Create(object result)
  {
   return CommonReturnType.Create(result, "success");
  }
  
  public static CommonReturnType Create(object result, string status)
  {
   CommonReturnType type = new CommonReturnType();
   type.SetStatus(status);
   type.SetData(result);

   return type;
  }

  public string GetStatus()
  {
   return status;
  }

  public void SetStatus(string status)
  {
   this.status = status;
  }

  public object GetData()
  {
   return data;
  }

  public void SetData(object data)
  {
   this.data = data;
  }
 }

最后推薦一個(gè)類(lèi)庫(kù),這是我在Nuget上發(fā)現(xiàn)的枚舉類(lèi)庫(kù),地址:https://github.com/ardalis/SmartEnum

好了,先分享到這里,希望對(duì)你有幫助和啟發(fā)。

參考資料:

(1)https://docs.microsoft.com/zh-cn/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types

(2)https://ardalis.com/enum-alternatives-in-c

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • .Net Core創(chuàng)建Api進(jìn)行文件上傳功能

    .Net Core創(chuàng)建Api進(jìn)行文件上傳功能

    這篇文章主要介紹了.Net Core創(chuàng)建Api進(jìn)行文件上傳,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • asp.net 細(xì)說(shuō)文件讀寫(xiě)操作(讀寫(xiě)鎖)

    asp.net 細(xì)說(shuō)文件讀寫(xiě)操作(讀寫(xiě)鎖)

    開(kāi)發(fā)過(guò)程中,我們玩玩需要大量與文件交互,讀文件,寫(xiě)文件已成家常便飯,本地運(yùn)行完美,但一上到投產(chǎn)環(huán)境,往往會(huì)出現(xiàn)很多令人措手不及的意外,或開(kāi)發(fā)中的煩惱,因此,我對(duì)普通的C#文件操作做了一次總結(jié)
    2011-12-12
  • ASP.NET兩個(gè)截取字符串的方法分享

    ASP.NET兩個(gè)截取字符串的方法分享

    這篇文章介紹了ASP.NET兩個(gè)截取字符串的方法,有需要的朋友可以參考一下
    2013-11-11
  • SQL通用存儲(chǔ)過(guò)程分頁(yè),支持多表聯(lián)合

    SQL通用存儲(chǔ)過(guò)程分頁(yè),支持多表聯(lián)合

    以前用.net寫(xiě)分頁(yè)存儲(chǔ)過(guò)程時(shí)老是一張表就要寫(xiě)一個(gè)procedure.很忙煩.后來(lái)有空就整合了一下,做了一個(gè)通用的sql分頁(yè)存儲(chǔ),支持多表聯(lián)合查詢(xún)分頁(yè).寫(xiě)的不好的地方,希望大鳥(niǎo)們多多指導(dǎo).使的查詢(xún)速度更快.
    2011-11-11
  • .Net?Core日志記錄之第三方框架Serilog

    .Net?Core日志記錄之第三方框架Serilog

    這篇文章介紹了.Net?Core日志記錄之第三方框架Serilog,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • asp.net生成Excel并導(dǎo)出下載五種實(shí)現(xiàn)方法

    asp.net生成Excel并導(dǎo)出下載五種實(shí)現(xiàn)方法

    有關(guān)Excel下載的文章網(wǎng)上想必有很多,利用閑暇時(shí)間整理了一些有Excel下載方法的文章,接下來(lái)介紹五種實(shí)現(xiàn)Excel下載的方法,感興趣的朋友可以了解下,或許對(duì)你學(xué)習(xí)Excel下載有所幫助
    2013-02-02
  • 在ASP.NET Core中顯示自定義的錯(cuò)誤頁(yè)面

    在ASP.NET Core中顯示自定義的錯(cuò)誤頁(yè)面

    大家在用瀏覽器訪問(wèn)服務(wù)器時(shí),不同情況下會(huì)返回不同的信息。服務(wù)器發(fā)生錯(cuò)誤就會(huì)返回錯(cuò)誤信息,我們最熟悉的就是404錯(cuò)誤頁(yè)面,但是這里我想和大家分享下在ASP.NET Core中如何顯示自定義的500或404錯(cuò)誤頁(yè)面,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-12-12
  • 快速入門(mén)ASP.NET Core看這篇就夠了

    快速入門(mén)ASP.NET Core看這篇就夠了

    ASP.NET Core 是一個(gè)由微軟創(chuàng)建的,用于構(gòu)建 web 應(yīng)用、API、微服務(wù) 的 web 框架。通過(guò)本文的學(xué)習(xí)就能快速的入門(mén)ASP.NET Core,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • ASP.NET實(shí)現(xiàn)頁(yè)面?zhèn)髦档膸追N方法小結(jié)

    ASP.NET實(shí)現(xiàn)頁(yè)面?zhèn)髦档膸追N方法小結(jié)

    這篇文章介紹了ASP.NET實(shí)現(xiàn)頁(yè)面?zhèn)髦档膸追N方法,有需要的朋友可以參考一下
    2013-11-11
  • 網(wǎng)頁(yè)(aspx)與用戶(hù)控件(ascx)交互邏輯處理實(shí)現(xiàn)

    網(wǎng)頁(yè)(aspx)與用戶(hù)控件(ascx)交互邏輯處理實(shí)現(xiàn)

    為了以后好維護(hù),把幾個(gè)頁(yè)面(ASPX)相同的部分抽取放在一個(gè)用戶(hù)控件(ASCX)上,現(xiàn)在把邏輯分享下,感興趣的各位可以參考下哈
    2013-03-03

最新評(píng)論

湖口县| 玛纳斯县| 筠连县| 广河县| 张北县| 交口县| 齐齐哈尔市| 宁强县| 榕江县| 镇沅| 丽江市| 临澧县| 二连浩特市| 平乡县| 平安县| 固镇县| 教育| 吉木乃县| 嘉定区| 南康市| 嘉鱼县| 抚宁县| 明溪县| 武陟县| 双城市| 驻马店市| 措美县| 清丰县| 洱源县| 石河子市| 都昌县| 图木舒克市| 博白县| 上饶县| 文登市| 娄底市| 安图县| 措勤县| 任丘市| 南召县| 房山区|