主頁 > .NET開發 > 開源專案Humanizer介紹

開源專案Humanizer介紹

2020-09-16 20:28:41 .NET開發

  Humanizer 能夠滿足您所有.Net關于操作和展示以下型別的需求,包括字串、列舉、日期、時間、時間跨度、數字和數量,它采用 MIT 進行授權分發,

 

1、人性化字串

人性化的字串擴展名使您可以將原本由計算機處理的字串轉換為更具可讀性的人性化字串, 它的基礎是在BDDfy框架中設定的,在該框架中,類名,方法名和屬性被轉換為易于閱讀的句子,

"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence"

"Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence"

"Underscored_input_String_is_turned_INTO_sentence".Humanize() => "Underscored input String is turned INTO sentence"

請注意,僅包含大寫字母且僅包含一個單詞的字串始終被視為首字母縮寫詞(無論其長度如何), 為了確保任何字串都將始終被人性化,您必須使用轉換(請參見下面的Transform方法):

// acronyms are left intact
"HTML".Humanize() => "HTML"

// any unbroken upper case string is treated as an acronym
"HUMANIZER".Humanize() => "HUMANIZER"
"HUMANIZER".Transform(To.LowerCase, To.TitleCase) => "Humanizer"

您還可以指定所需的字母大小寫:

"CanReturnTitleCase".Humanize(LetterCasing.Title) => "Can Return Title Case"

"Can_return_title_Case".Humanize(LetterCasing.Title) => "Can Return Title Case"

"CanReturnLowerCase".Humanize(LetterCasing.LowerCase) => "can return lower case"

"CanHumanizeIntoUpperCase".Humanize(LetterCasing.AllCaps) => "CAN HUMANIZE INTO UPPER CASE"

LetterCasing API和接受它的方法是V0.2時代的遺留物,將來會不推薦使用, 代替的是,您可以使用下面介紹的Transform方法,

 

2、非人性化的字串

就像您可以將計算機友好的字串人性化為人類友好的字串一樣,您也可以將人類友好的字串人性化為計算機友好的字串:

"Pascal case input string is turned into sentence".Dehumanize() => "PascalCaseInputStringIsTurnedIntoSentence"

 

3、轉換字串

有一種Transform方法可以代替接受LetterCasing的LetterCasing,ApplyCase和Humanize多載, 轉換方法簽名如下:

string Transform(this string input, params IStringTransformer[] transformers)

對于字母大小寫,還有一些IStringTransformer的現成實作:

"Sentence casing".Transform(To.LowerCase) => "sentence casing"
"Sentence casing".Transform(To.SentenceCase) => "Sentence casing"
"Sentence casing".Transform(To.TitleCase) => "Sentence Casing"
"Sentence casing".Transform(To.UpperCase) => "SENTENCE CASING"

LowerCase是To類的公共靜態屬性,它回傳私有ToLowerCase類的實體,該實體實作IStringTransformer并知道如何將字串轉換為小寫,

與ApplyCase和LetterCasing相比,使用Transform和IStringTransformer的好處是LetterCasing是列舉,并且您只能使用框架中的內容,而IStringTransformer是可以在代碼庫中一次實作并與Transform方法一起使用的介面,從而可以輕松擴展 ,

 

4、截斷字串

您可以使用Truncate方法截斷字串:

"Long text to truncate".Truncate(10) => "Long text…"

默認情況下,“ ...”字符用于截斷字串, 使用'...'字符而不是“ ...”的優點是前者僅使用一個字符,因此允許在截斷之前顯示更多文本, 如果需要,還可以提供自己的截斷字串:

"Long text to truncate".Truncate(10, "---") => "Long te---"

默認的截斷策略Truncator.FixedLength是將輸入字串截斷為特定長度,包括截斷字串的長度, 還有兩種其他的截斷器策略:一種用于固定數量的(字母數字)字符,另一種用于固定數量的單詞, 要在截斷時使用特定的截斷器,前面示例中顯示的兩個Truncate方法都具有多載,允許您指定用于截斷的ITruncator實體, 以下是有關如何使用提供的三個截斷符的示例:

"Long text to truncate".Truncate(10, Truncator.FixedLength) => "Long text…"
"Long text to truncate".Truncate(10, "---", Truncator.FixedLength) => "Long te---"

"Long text to truncate".Truncate(6, Truncator.FixedNumberOfCharacters) => "Long t…"
"Long text to truncate".Truncate(6, "---", Truncator.FixedNumberOfCharacters) => "Lon---"

"Long text to truncate".Truncate(2, Truncator.FixedNumberOfWords) => "Long text…"
"Long text to truncate".Truncate(2, "---", Truncator.FixedNumberOfWords) => "Long text---"

請注意,您還可以通過實作ITruncator介面來使用創建自己的截斷器,

還有一個選項可以選擇是從開頭(TruncateFrom.Left)還是結尾(TruncateFrom.Right)截斷字串, 如上面的示例所示,默認設定為右側, 下面的示例顯示如何從字串的開頭截斷:

"Long text to truncate".Truncate(10, Truncator.FixedLength, TruncateFrom.Left) => "… truncate"
"Long text to truncate".Truncate(10, "---", Truncator.FixedLength, TruncateFrom.Left) => "---runcate"

"Long text to truncate".Truncate(10, Truncator.FixedNumberOfCharacters, TruncateFrom.Left) => "…o truncate"
"Long text to truncate".Truncate(16, "---", Truncator.FixedNumberOfCharacters, TruncateFrom.Left) => "---ext to truncate"

"Long text to truncate".Truncate(2, Truncator.FixedNumberOfWords, TruncateFrom.Left) => "…to truncate"
"Long text to truncate".Truncate(2, "---", Truncator.FixedNumberOfWords, TruncateFrom.Left) => "---to truncate"

 

5、格式化字串

您可以使用FormatWith()方法設定字串格式:

"To be formatted -> {0}/{1}.".FormatWith(1, "A") => "To be formatted -> 1/A."

這是基于String.Format的擴展方法,因此確切的規則適用于它, 如果format為null,則將引發ArgumentNullException, 如果傳遞的引數數目較少,則會引發String.FormatException例外,

您還可以指定區域性以顯式用作FormatWith()方法的第一個引數:

"{0:N2}".FormatWith(new CultureInfo("ru-RU"), 6666.66) => "6 666,66"

如果未指定區域性,則使用當前執行緒的當前區域性,

 

6、人性化列舉

直接在列舉成員上呼叫ToString通常會給用戶帶來不理想的輸出, 解決方案通常是使用DescriptionAttribute資料注釋,然后在運行時讀取該注釋以獲得更友好的輸出, 那是一個很好的解決方案, 但是通常,我們只需要在列舉成員的單詞之間放置一些空格-這就是String.Humanize()的優點, 對于像這樣的列舉:

public enum EnumUnderTest
{
    [Description("Custom description")]
    MemberWithDescriptionAttribute,
    MemberWithoutDescriptionAttribute,
    ALLCAPITALS
}

你會得到:

// DescriptionAttribute is honored
EnumUnderTest.MemberWithDescriptionAttribute.Humanize() => "Custom description"

// In the absence of Description attribute string.Humanizer kicks in
EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize() => "Member without description attribute"

// Of course you can still apply letter casing
EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize().Transform(To.TitleCase) => "Member Without Description Attribute"

您不僅限于DescriptionAttribute作為自定義描述, 應用于具有字串Description屬性的列舉成員的任何屬性都將計數, 這是為了幫助缺少DescriptionAttribute的平臺,也允許使用DescriptionAttribute的子類,

您甚至可以配置attibute屬性的名稱以用作描述,

Configurator.EnumDescriptionPropertyLocator = p => p.Name == "Info"

如果需要提供本地化的描述,則可以改用DisplayAttribute資料注釋,

public enum EnumUnderTest
{
    [Display(Description = "EnumUnderTest_Member", ResourceType = typeof(Project.Resources))]
    Member
}

你會得到:

EnumUnderTest.Member.Humanize() => "content" // from Project.Resources found under "EnumUnderTest_Member" resource key

希望這將有助于避免亂定義帶有不必要屬性的列舉!

 

7、使列舉非人性化

將字串人性化,使其原本是人性化的列舉! 該API如下所示:

public static TTargetEnum DehumanizeTo<TTargetEnum>(this string input)

用法是:

"Member without description attribute".DehumanizeTo<EnumUnderTest>() => EnumUnderTest.MemberWithoutDescriptionAttribute

就像Humanize API一樣,它使用Description屬性, 您無需提供在人性化程序中提供的外殼:它可以弄清楚,

當在編譯時不知道原始Enum時,還有一個非泛型對應項:

public static Enum DehumanizeTo(this string input, Type targetEnum, NoMatch onNoMatch = NoMatch.ThrowsException)

可以像這樣使用:

"Member without description attribute".DehumanizeTo(typeof(EnumUnderTest)) => EnumUnderTest.MemberWithoutDescriptionAttribute

默認情況下,兩個方法都無法將提供的輸入與目標列舉進行匹配時拋出NoMatchFoundException, 在非泛型方法中,您還可以通過將第二個可選引數設定為NoMatch.ReturnsNull來要求該方法回傳null,

 

8、人性化DateTime

您可以對DateTime或DateTimeOffset的實體進行人性化,并回傳一個字串,該字串告訴您時間上的倒退或前進時間:

DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"

DateTime.UtcNow.AddHours(30).Humanize() => "tomorrow"
DateTime.UtcNow.AddHours(2).Humanize() => "2 hours from now"

DateTimeOffset.UtcNow.AddHours(1).Humanize() => "an hour from now"

Humanizer支持本地和UTC日期以及具有偏移量的日期(DateTimeOffset), 您還可以提供要與輸入日期進行比較的日期, 如果為null,它將使用當前日期作為比較基礎, 另外,可以明確指定要使用的文化, 如果不是,則使用當前執行緒的當前UI文化, 這是API簽名:

public static string Humanize(this DateTime input, bool utcDate = true, DateTime? dateToCompareAgainst = null, CultureInfo culture = null)
public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToCompareAgainst = null, CultureInfo culture = null)

此方法有許多本地化版本, 以下是一些示例:

// In ar culture
DateTime.UtcNow.AddDays(-1).Humanize() => "???"
DateTime.UtcNow.AddDays(-2).Humanize() => "??? ?????"
DateTime.UtcNow.AddDays(-3).Humanize() => "??? 3 ????"
DateTime.UtcNow.AddDays(-11).Humanize() => "??? 11 ???"

// In ru-RU culture
DateTime.UtcNow.AddMinutes(-1).Humanize() => "минуту назад"
DateTime.UtcNow.AddMinutes(-2).Humanize() => "2 минуты назад"
DateTime.UtcNow.AddMinutes(-10).Humanize() => "10 минут назад"
DateTime.UtcNow.AddMinutes(-21).Humanize() => "21 минуту назад"
DateTime.UtcNow.AddMinutes(-22).Humanize() => "22 минуты назад"
DateTime.UtcNow.AddMinutes(-40).Humanize() => "40 минут назад"

DateTime.Humanize有兩種策略:如上所述的默認策略和基于精度的策略, 要使用基于精度的策略,您需要對其進行配置:

Configurator.DateTimeHumanizeStrategy = new PrecisionDateTimeHumanizeStrategy(precision: .75);
Configurator.DateTimeOffsetHumanizeStrategy = new PrecisionDateTimeOffsetHumanizeStrategy(precision: .75); // configure when humanizing DateTimeOffset

默認精度設定為.75,但是您也可以傳遞所需的精度, 將精度設定為0.75:

44 seconds => 44 seconds ago/from now
45 seconds => one minute ago/from now
104 seconds => one minute ago/from now
105 seconds => two minutes ago/from now

25 days => a month ago/from now

日期沒有非人性化,因為人性化是有損的轉換,并且人類友好的日期是不可逆的,

 

9、人性化的時間跨度

您可以在TimeSpan上呼叫Humanize以獲得人性化的表示形式:

TimeSpan.FromMilliseconds(1).Humanize() => "1 millisecond"
TimeSpan.FromMilliseconds(2).Humanize() => "2 milliseconds"
TimeSpan.FromDays(1).Humanize() => "1 day"
TimeSpan.FromDays(16).Humanize() => "2 weeks"

TimeSpan.Humanize有一個可選的precision引數,它允許您指定回傳值的精度, 精度的默認值為1,這意味著僅回傳最大的時間單位,如您在TimeSpan.FromDays(16).Humanize()中看到的那樣, 以下是一些指定精度的示例:

TimeSpan.FromDays(1).Humanize(precision:2) => "1 day" // no difference when there is only one unit in the provided TimeSpan
TimeSpan.FromDays(16).Humanize(2) => "2 weeks, 2 days"

// the same TimeSpan value with different precision returns different results
TimeSpan.FromMilliseconds(1299630020).Humanize() => "2 weeks"
TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"
TimeSpan.FromMilliseconds(1299630020).Humanize(4) => "2 weeks, 1 day, 1 hour, 30 seconds"
TimeSpan.FromMilliseconds(1299630020).Humanize(5) => "2 weeks, 1 day, 1 hour, 30 seconds, 20 milliseconds"

默認情況下,使用精度引數時,空時間單位不計入回傳值的精度, 如果您不需要這種行為,則可以將多載的TimeSpan.Humanize方法與countEmptyUnits引數一起使用, 前導的空時間單位永遠不會計數, 這是顯示空單位計數的區別的示例:

TimeSpan.FromMilliseconds(3603001).Humanize(3) => "1 hour, 3 seconds, 1 millisecond"
TimeSpan.FromMilliseconds(3603001).Humanize(3, countEmptyUnits:true) => "1 hour, 3 seconds"

此方法有許多本地化版本:

// in de-DE culture
TimeSpan.FromDays(1).Humanize() => "Ein Tag"
TimeSpan.FromDays(2).Humanize() => "2 Tage"

// in sk-SK culture
TimeSpan.FromMilliseconds(1).Humanize() => "1 milisekunda"
TimeSpan.FromMilliseconds(2).Humanize() => "2 milisekundy"
TimeSpan.FromMilliseconds(5).Humanize() => "5 milisekúnd"

可以明確指定要使用的文化, 如果不是,則使用當前執行緒的當前UI文化, 例:

TimeSpan.FromDays(1).Humanize(culture: "ru-RU") => "один день"

另外,可以指定最短的時間單位,以避免滾動到較小的單位, 例如:

TimeSpan.FromMilliseconds(122500).Humanize(minUnit: TimeUnit.Second) => "2 minutes, 2 seconds"    // instead of 2 minutes, 2 seconds, 500 milliseconds
TimeSpan.FromHours(25).Humanize(minUnit: TimeUnit.Day) => "1 Day"   //instead of 1 Day, 1 Hour

另外,可以指定最大時間單位以避免累加到下一個最大單位, 例如:

TimeSpan.FromDays(7).Humanize(maxUnit: TimeUnit.Day) => "7 days"    // instead of 1 week
TimeSpan.FromMilliseconds(2000).Humanize(maxUnit: TimeUnit.Millisecond) => "2000 milliseconds"    // instead of 2 seconds

默認的maxUnit為TimeUnit.Week,因為它可以提供準確的結果, 您可以將此值增加到TimeUnit.Month或TimeUnit.Year,這將為您提供基于每年365.2425天和每月30.436875天的近似值, 因此,月份的間隔為30到31天,每四年為366天,

TimeSpan.FromDays(486).Humanize(maxUnit: TimeUnit.Year, precision: 7) => "1 year, 3 months, 29 days" // One day further is 1 year, 4 month
TimeSpan.FromDays(517).Humanize(maxUnit: TimeUnit.Year, precision: 7) => "1 year, 4 months, 30 days" // This month has 30 days and one day further is 1 year, 5 months

如果有多個時間單位,則使用“,”字串將它們組合起來:

TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"

當TimeSpan為零時,默認行為將回傳“ 0”加上最小時間單位, 但是,如果在呼叫Humanize時將true分配給toWords,則該方法將回傳“ no time”, 例如:

TimeSpan.Zero.Humanize(1) => "0 milliseconds"
TimeSpan.Zero.Humanize(1, toWords: true) => "no time"
TimeSpan.Zero.Humanize(1, minUnit: Humanizer.Localisation.TimeUnit.Second) => "0 seconds"

使用collectionSeparator引數,可以指定自己的分隔符字串:

TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: " - ") => "2 weeks - 1 day - 1 hour"

也可以使用當前區域性的集合格式化程式來組合時間單位, 為此,將null指定為collectionSeparator引數:

// in en-US culture
TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: null) => "2 weeks, 1 day, and 1 hour"

// in de-DE culture
TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: null) => "2 Wochen, Ein Tag und Eine Stunde"

如果單詞優先于數字,則可以設定toWords:true引數,以將人性化的TimeSpan中的數字轉換為單詞:

TimeSpan.FromMilliseconds(1299630020).Humanize(3,toWords:true)=>“兩個星期,一天,一個小時”

 

10、人性化集合

您可以在任何IEnumerable上呼叫Humanize,以獲取格式正確的字串,該字串表示集合中的物件, 默認情況下,將在每個專案上呼叫ToString()以獲取其表示形式,但是可以將格式化函式傳遞給Humanize, 此外,提供了一個默認的分隔符(英語中為“ and”),但是可以將其他分隔符傳遞給Humanize,

例如:

class SomeClass
{
    public string SomeString;
    public int SomeInt;
    public override string ToString()
    {
        return "Specific String";
    }
}

string FormatSomeClass(SomeClass sc)
{
    return string.Format("SomeObject #{0} - {1}", sc.SomeInt, sc.SomeString);
}

var collection = new List<SomeClass>
{
    new SomeClass { SomeInt = 1, SomeString = "One" },
    new SomeClass { SomeInt = 2, SomeString = "Two" },
    new SomeClass { SomeInt = 3, SomeString = "Three" }
};

collection.Humanize()                                    // "Specific String, Specific String, and Specific String"
collection.Humanize("or")                                // "Specific String, Specific String, or Specific String"
collection.Humanize(FormatSomeClass)                     // "SomeObject #1 - One, SomeObject #2 - Two, and SomeObject #3 - Three"
collection.Humanize(sc => sc.SomeInt.Ordinalize(), "or") // "1st, 2nd, or 3rd"

修剪專案,并跳過空白(NullOrWhitespace)專案, 這導致干凈的逗號標點, (如果有自定義格式器功能,則此功能僅適用于格式器的輸出,)

您可以通過實作ICollectionFormatter并向Configurator.CollectionFormatters注冊它來提供自己的集合格式化程式,

 

11、Inflector 方法

還有一些 inflector 方法:

 

復數

在考慮不規則和不可數詞的情況下,將提供的輸入復數化:

"Man".Pluralize() => "Men"
"string".Pluralize() => "strings"

通常,您將對單個單詞呼叫Pluralize,但如果不確定單詞的奇異性,則可以使用可選的inputIsKnownToBeSingular引數呼叫該方法:

"Men".Pluralize(inputIsKnownToBeSingular: false) => "Men"
"Man".Pluralize(inputIsKnownToBeSingular: false) => "Men"
"string".Pluralize(inputIsKnownToBeSingular: false) => "strings"

具有復數引數的Pluralize多載已過時,在2.0版中已洗掉,

 

單數化

單數將提供的輸入單數化,同時考慮不規則和不可數的單詞:

"Men".Singularize() => "Man"
"strings".Singularize() => "string"

通常,您會在一個復數單詞上呼叫單數化,但是如果不確定該單詞的復數形式,則可以使用可選的inputIsKnownToBePlural引數呼叫該方法:

"Men".Singularize(inputIsKnownToBePlural: false) => "Man"
"Man".Singularize(inputIsKnownToBePlural: false) => "Man"
"strings".Singularize(inputIsKnownToBePlural: false) => "string"

具有復數引數的Singularize多載已過時,并且在2.0版中已洗掉,

 

12、添加單詞

有時,您可能需要從單數/復數詞匯表中添加一條規則(以下示例已在Inflector使用的默認詞匯表中):

// Adds a word to the vocabulary which cannot easily be pluralized/singularized by RegEx.
// Will match both "salesperson" and "person".
Vocabularies.Default.AddIrregular("person", "people");

// To only match "person" and not "salesperson" you would pass false for the 'matchEnding' parameter.
Vocabularies.Default.AddIrregular("person", "people", matchEnding: false);

// Adds an uncountable word to the vocabulary.  Will be ignored when plurality is changed:
Vocabularies.Default.AddUncountable("fish");

// Adds a rule to the vocabulary that does not follow trivial rules for pluralization:
Vocabularies.Default.AddPlural("bus", "buses");

// Adds a rule to the vocabulary that does not follow trivial rules for singularization
// (will match both "vertices" -> "vertex" and "indices" -> "index"):
Vocabularies.Default.AddSingular("(vert|ind)ices$", "$1ex");

到數量

很多時候,您想呼叫單數化和復數化為單詞加上數字, 例如 “ 2個請求”,“ 3個男人”, ToQuantity為提供的單詞加上數字前綴,并相應地對該單詞進行復數或單數化:

"case".ToQuantity(0) => "0 cases"
"case".ToQuantity(1) => "1 case"
"case".ToQuantity(5) => "5 cases"
"man".ToQuantity(0) => "0 men"
"man".ToQuantity(1) => "1 man"
"man".ToQuantity(2) => "2 men"

ToQuantity可以判斷輸入單詞是單數還是復數,并在必要時將單數或復數:

"men".ToQuantity(2) => "2 men"
"process".ToQuantity(2) => "2 processes"
"process".ToQuantity(1) => "1 process"
"processes".ToQuantity(2) => "2 processes"
"processes".ToQuantity(1) => "1 process"

您還可以將第二個引數ShowQuantityAs傳遞給ToQuantity,以指定希望如何輸出提供的數量, 默認值為ShowQuantityAs.Numeric,這是我們在上面看到的, 其他兩個值是ShowQuantityAs.Words和ShowQuantityAs.None,

"case".ToQuantity(5, ShowQuantityAs.Words) => "five cases"
"case".ToQuantity(5, ShowQuantityAs.None) => "cases"

還有一個多載,允許您格式化數字, 您可以傳遞要使用的格式和文化,

"dollar".ToQuantity(2, "C0", new CultureInfo("en-US")) => "$2 dollars"
"dollar".ToQuantity(2, "C2", new CultureInfo("en-US")) => "$2.00 dollars"
"cases".ToQuantity(12000, "N0") => "12,000 cases"

序數化

序數化將數字轉換為序數字串,用于表示有序序列(例如1st,2nd,3rd,4th)中的位置:

1.Ordinalize() => "1st"
5.Ordinalize() => "5th"

您還可以在數字字串上呼叫Ordinalize并獲得相同的結果:“ 21” .Ordinalize()=>“ 21st”

序數化還支持兩種形式的語法性別, 您可以將一個引數傳遞給Ordinalize,以指定數字應以哪種性別輸出,可能的值為GrammaticalGender.Masculine,GrammmicalGender.Feminine和GrammaticalGender.Neuter:

// for Brazilian Portuguese locale
1.Ordinalize(GrammaticalGender.Masculine) => ""
1.Ordinalize(GrammaticalGender.Feminine) => ""
1.Ordinalize(GrammaticalGender.Neuter) => ""
"2".Ordinalize(GrammaticalGender.Masculine) => ""
"2".Ordinalize(GrammaticalGender.Feminine) => ""
"2".Ordinalize(GrammaticalGender.Neuter) => ""

顯然,這僅適用于某些文化, 對于其他通過性別或根本不通過的人,結果沒有任何區別,

標題化

Titleize將輸入的單詞轉換為Title大小寫; 等效于“某些標題”,Humanize(LetterCasing.Title)

Pascalize

Pascalize將輸入的單詞轉換為UpperCamelCase,還洗掉下劃線和空格:

"some_title for something".Pascalize() => "SomeTitleForSomething"

Camelize

Camelize的行為與Pascalize相同,但第一個字符為小寫:

"some_title for something".Camelize() => "someTitleForSomething"

下劃線

Underscore用下劃線分隔輸入的單詞:

"SomeTitle".Underscore() => "some_title"

Dasherize & Hyphenate

Dasherize和Hyphenate用下劃線替換下劃線:

"some_title".Dasherize() => "some-title"
"some_title".Hyphenate() => "some-title"
Kebaberize Kebaberize用連字符分隔輸入的單詞,所有單詞都轉換為小寫
"SomeText".Kebaberize() => "some-text"

 

13、流利的日期

Humanizer提供了一種流利的API來處理DateTime和TimeSpan,如下所示:

TimeSpan方法:

2.Milliseconds() => TimeSpan.FromMilliseconds(2)
2.Seconds() => TimeSpan.FromSeconds(2)
2.Minutes() => TimeSpan.FromMinutes(2)
2.Hours() => TimeSpan.FromHours(2)
2.Days() => TimeSpan.FromDays(2)
2.Weeks() => TimeSpan.FromDays(14)

每月或一年都沒有流利的API,因為一個月可能有28到31天,一年可能是365或366天,

您可以使用這些方法來替換

DateTime.Now.AddDays(2).AddHours(3).AddMinutes(-5)

DateTime.Now + 2.Days() + 3.Hours() - 5.Minutes()

還可以使用三類流利的方法來處理DateTime:

In.TheYear(2010) // Returns the first of January of 2010
In.January // Returns 1st of January of the current year
In.FebruaryOf(2009) // Returns 1st of February of 2009

In.One.Second //  DateTime.UtcNow.AddSeconds(1);
In.Two.SecondsFrom(DateTime dateTime)
In.Three.Minutes // With corresponding From method
In.Three.Hours // With corresponding From method
In.Three.Days // With corresponding From method
In.Three.Weeks // With corresponding From method
In.Three.Months // With corresponding From method
In.Three.Years // With corresponding From method

On.January.The4th // Returns 4th of January of the current year
On.February.The(12) // Returns 12th of Feb of the current year

和一些擴展方法:

var someDateTime = new DateTime(2011, 2, 10, 5, 25, 45, 125);

// Returns new DateTime(2008, 2, 10, 5, 25, 45, 125) changing the year to 2008
someDateTime.In(2008)

// Returns new DateTime(2011, 2, 10, 2, 25, 45, 125) changing the hour to 2:25:45.125
someDateTime.At(2)

// Returns new DateTime(2011, 2, 10, 2, 20, 15, 125) changing the time to 2:20:15.125
someDateTime.At(2, 20, 15)

// Returns new DateTime(2011, 2, 10, 12, 0, 0) changing the time to 12:00:00.000
someDateTime.AtNoon()

// Returns new DateTime(2011, 2, 10, 0, 0, 0) changing the time to 00:00:00.000
someDateTime.AtMidnight()

顯然,您也可以將這些方法鏈接在一起, 例如 2010年11月13日在中午+ 5分鐘()

 

14、數字到數字

Humanizer提供了一種流暢的API,該API以更清晰的方式生成(通常是很大的)數字:

1.25.Billions() => 1250000000
3.Hundreds().Thousands() => 300000

 

15、數字到單詞

Humanizer可以使用ToWords擴展名將數字更改為單詞:

1.ToWords() => "one"
10.ToWords() => "ten"
11.ToWords() => "eleven"
122.ToWords() => "one hundred and twenty-two"
3501.ToWords() => "three thousand five hundred and one"

您還可以將第二個引數GrammaticalGender傳遞給ToWords,以指定應該輸出數字的性別,可能的值為GrammaticalGender.Masculine,GrammaticalGender.Feminine和GrammaticalGender.Neuter:

// for Russian locale
1.ToWords(GrammaticalGender.Masculine) => "один"
1.ToWords(GrammaticalGender.Feminine) => "одна"
1.ToWords(GrammaticalGender.Neuter) => "одно"
// for Arabic locale
1.ToWords(GrammaticalGender.Masculine) => "????"
1.ToWords(GrammaticalGender.Feminine) => "?????"
1.ToWords(GrammaticalGender.Neuter) => "????"
(-1).ToWords() => "???? ????"

顯然,這僅適用于某些文化, 對于傳遞性別的其他人來說,結果沒有任何區別,

另外,可以明確指定要使用的文化, 如果不是,則使用當前執行緒的當前UI文化, 這是一個例子:

11.ToWords(new CultureInfo("en")) => "eleven"
1.ToWords(GrammaticalGender.Masculine, new CultureInfo("ru")) => "один"

 

16、數字到序數詞

這是將ToWords與Ordinalize混合在一起的一種, 您可以在數字上呼叫ToOrdinalWords以獲得數字中單詞的序號表示! 例如:

0.ToOrdinalWords() => "zeroth"
1.ToOrdinalWords() => "first"
2.ToOrdinalWords() => "second"
8.ToOrdinalWords() => "eighth"
10.ToOrdinalWords() => "tenth"
11.ToOrdinalWords() => "eleventh"
12.ToOrdinalWords() => "twelfth"
20.ToOrdinalWords() => "twentieth"
21.ToOrdinalWords() => "twenty first"
121.ToOrdinalWords() => "hundred and twenty first"

ToOrdinalWords也支持語法性別, 您可以將第二個引數傳遞給ToOrdinalWords以指定輸出的性別, 可能的值為GrammaticalGender.Masculine,GrammmicalGender.Feminine和GrammaticalGender.Neuter:

// for Brazilian Portuguese locale
1.ToOrdinalWords(GrammaticalGender.Masculine) => "primeiro"
1.ToOrdinalWords(GrammaticalGender.Feminine) => "primeira"
1.ToOrdinalWords(GrammaticalGender.Neuter) => "primeiro"
2.ToOrdinalWords(GrammaticalGender.Masculine) => "segundo"
2.ToOrdinalWords(GrammaticalGender.Feminine) => "segunda"
2.ToOrdinalWords(GrammaticalGender.Neuter) => "segundo"
// for Arabic locale
1.ToOrdinalWords(GrammaticalGender.Masculine) => "?????"
1.ToOrdinalWords(GrammaticalGender.Feminine) => "??????"
1.ToOrdinalWords(GrammaticalGender.Neuter) => "?????"
2.ToOrdinalWords(GrammaticalGender.Masculine) => "??????"
2.ToOrdinalWords(GrammaticalGender.Feminine) => "???????"
2.ToOrdinalWords(GrammaticalGender.Neuter) => "??????"

顯然,這僅適用于某些文化, 對于傳遞性別的其他人來說,結果沒有任何區別,

另外,可以明確指定要使用的文化, 如果不是,則使用當前執行緒的當前UI文化, 這是一個例子:

10.ToOrdinalWords(new CultureInfo("en-US")) => "tenth"
1.ToOrdinalWords(GrammaticalGender.Masculine, new CulureInfo("pt-BR")) => "primeiro"

 

17、日期時間到序數詞

這是Ordinalize的擴展

// for English UK locale
new DateTime(2015, 1, 1).ToOrdinalWords() => "1st January 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "12th February 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "22nd March 2015"
// for English US locale
new DateTime(2015, 1, 1).ToOrdinalWords() => "January 1st, 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "February 12th, 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "March 22nd, 2015"

ToOrdinalWords也支持語法大小寫, 您可以將第二個引數傳遞給ToOrdinalWords以指定輸出的大小寫, 可能的值是GrammaticalCase.Nominative,GrammmicalCase.Genitive,GrammmicalCase.Dative,GrammmicalCase.Accusative,GrammmicalCase.Instrumental和GraammaticalGender,介詞:

顯然,這僅適用于某些文化, 對于其他人來說,通過案例不會對結果產生任何影響,

 

18、羅馬數字

Humanizer可以使用ToRoman擴展名將數字更改為羅馬數字, 數字1到10可以用羅馬數字表示如下:

1.ToRoman() => "I"
2.ToRoman() => "II"
3.ToRoman() => "III"
4.ToRoman() => "IV"
5.ToRoman() => "V"
6.ToRoman() => "VI"
7.ToRoman() => "VII"
8.ToRoman() => "VIII"
9.ToRoman() => "IX"
10.ToRoman() => "X"

也可以使用FromRoman擴展名進行反向操作,

"I".FromRoman() => 1
"II".FromRoman() => 2
"III".FromRoman() => 3
"IV".FromRoman() => 4
"V".FromRoman() => 5

請注意,只有小于4000的整數才能轉換為羅馬數字,

 

19、公制數字 Humanizer可以使用ToMetric擴展名將數字更改為公制數字, 數字1、1230和0.1可以用公制數字表示,如下所示:
1d.ToMetric() => "1"
1230d.ToMetric() => "1.23k"
0.1d.ToMetric() => "100m"

也可以使用FromMetric擴展進行相反的操作,

1d.ToMetric() => "1"
1230d.ToMetric() => "1.23k"
0.1d.ToMetric() => "100m"

"1".FromMetric() => 1
"1.23k".FromMetric() => 1230
"100m".FromMetric() => 0.1

 

20、位元組大小

Humanizer包含出色的ByteSize庫的埠, 對ByteSize進行了許多更改和添加,以使與ByteSize的互動更容易且與Humanizer API更加一致, 這是一些如何從數字轉換為位元組大小以及在大小幅值之間轉換的示例:

var fileSize = (10).Kilobytes();

fileSize.Bits      => 81920
fileSize.Bytes     => 10240
fileSize.Kilobytes => 10
fileSize.Megabytes => 0.009765625
fileSize.Gigabytes => 9.53674316e-6
fileSize.Terabytes => 9.31322575e-9

有幾種擴展方法可讓您將數字轉換為ByteSize實體:

3.Bits();
5.Bytes();
(10.5).Kilobytes();
(2.5).Megabytes();
(10.2).Gigabytes();
(4.7).Terabytes();

您還可以使用+/-運算子和加/減方法對值進行加/減:

var total = (10).Gigabytes() + (512).Megabytes() - (2.5).Gigabytes();
total.Subtract((2500).Kilobytes()).Add((25).Megabytes());

ByteSize物件包含兩個屬性,它們代表最大的度量標準前綴符號和值:

var maxFileSize = (10).Kilobytes();

maxFileSize.LargestWholeNumberSymbol;  // "KB"
maxFileSize.LargestWholeNumberValue;   // 10

如果要使用字串表示形式,則可以在ByteSize實體上互換呼叫ToString或Humanize:

7.Bits().ToString();           // 7 b
8.Bits().ToString();           // 1 B
(.5).Kilobytes().Humanize();   // 512 B
(1000).Kilobytes().ToString(); // 1000 KB
(1024).Kilobytes().Humanize(); // 1 MB
(.5).Gigabytes().Humanize();   // 512 MB
(1024).Gigabytes().ToString(); // 1 TB

您還可以選擇提供期望的字串表示形式的格式, 格式化程式可以包含要顯示的值的符號:b,B,KB,MB,GB,TB, 格式化程式使用內置的double.ToString方法,將#,##作為默認格式,該格式將數字四舍五入到小數點后兩位:

var b = (10.505).Kilobytes();

// Default number format is #.##
b.ToString("KB");         // 10.52 KB
b.Humanize("MB");         // .01 MB
b.Humanize("b");          // 86057 b

// Default symbol is the largest metric prefix value >= 1
b.ToString("#.#");        // 10.5 KB

// All valid values of double.ToString(string format) are acceptable
b.ToString("0.0000");     // 10.5050 KB
b.Humanize("000.00");     // 010.51 KB

// You can include number format and symbols
b.ToString("#.#### MB");  // .0103 MB
b.Humanize("0.00 GB");    // 0 GB
b.Humanize("#.## B");     // 10757.12 B

如果要使用完整單詞的字串表示形式,可以在ByteSize實體上呼叫ToFullWords:

7.Bits().ToFullWords();           // 7 bits
8.Bits().ToFullWords();           // 1 byte
(.5).Kilobytes().ToFullWords();   // 512 bytes
(1000).Kilobytes().ToFullWords(); // 1000 kilobytes
(1024).Kilobytes().ToFullWords(); // 1 megabyte
(.5).Gigabytes().ToFullWords();   // 512 megabytes
(1024).Gigabytes().ToFullWords(); // 1 terabyte

沒有Dehumanize方法可以將字串表示形式轉換回ByteSize實體, 但是您可以對ByteSize使用Parse和TryParse來做到這一點, 像其他TryParse方法一樣,ByteSize.TryParse回傳布林值,該值指示決議是否成功, 如果決議了該值,則將其輸出到提供的out引數:

 

ByteSize output;
ByteSize.TryParse("1.5mb", out output);

// Invalid
ByteSize.Parse("1.5 b");   // Can't have partial bits

// Valid
ByteSize.Parse("5b");
ByteSize.Parse("1.55B");
ByteSize.Parse("1.55KB");
ByteSize.Parse("1.55 kB "); // Spaces are trimmed
ByteSize.Parse("1.55 kb");
ByteSize.Parse("1.55 MB");
ByteSize.Parse("1.55 mB");
ByteSize.Parse("1.55 mb");
ByteSize.Parse("1.55 GB");
ByteSize.Parse("1.55 gB");
ByteSize.Parse("1.55 gb");
ByteSize.Parse("1.55 TB");
ByteSize.Parse("1.55 tB");
ByteSize.Parse("1.55 tb");

最后,如果您需要計算傳輸一定數量位元組的速率,則可以使用ByteSize的Per方法, Per方法接受一個引數-位元組的測量間隔; 這是傳輸位元組所花費的時間,

Per方法回傳具有Humanize方法的ByteRate類, 默認情況下,速率以秒為單位(例如MB / s), 但是,如果需要,可以在另一個間隔內將TimeUnit傳遞給Humanize, 有效間隔是TimeUnit.Second,TimeUnit.Minute和TimeUnit.Hour, 下面是每個間隔的示例以及位元組率的示例,

var size = ByteSize.FromMegabytes(10);
var measurementInterval = TimeSpan.FromSeconds(1);

var text = size.Per(measurementInterval).Humanize();
// 10 MB/s

text = size.Per(measurementInterval).Humanize(TimeUnit.Minute);
// 600 MB/min

text = size.Per(measurementInterval).Humanize(TimeUnit.Hour);
// 35.15625 GB/hour

您可以為人性化輸出的位元組部分指定格式:

 
19854651984.Bytes().Per(1.Seconds()).Humanize("#.##");
// 18.49 GB/s

 

21、角度到單詞

Humanizer包括將數字標題更改為單詞的方法, 標題可以是雙精度,而結果將是字串, 您可以選擇回傳標題的完整表示形式(例如,北,東,南或西),簡短表示形式(例如,N,E,S,W)還是Unicode箭頭字符(例如,↑,→,↓,←) ),

360.ToHeading();
// north
720.ToHeading();
// north

為了檢索標題的簡短版本,您可以使用以下呼叫:

180.ToHeading(true);
// S
360.ToHeading(true);
// N

請注意,文字表示的最大偏差為11.25°,

最重要的是,這些方法都有一個多載,您可以使用它提供一個CultureInfo物件,以確定要回傳的本地化結果,

要檢索表示標題的箭頭,請使用以下方法:

90.ToHeadingArrow();
//
225.ToHeadingArrow();
//

標題的箭頭表示最大偏差為22.5°,

為了檢索基于短文本表示形式的標題(例如N,E,S,W),可以使用以下方法:

"S".FromShortHeading();
// 180
"SW".FromShortHeading();
// 225

 

22、元組化

Humanizer 可以使用Tupleize將整數更改為其“元組”, 例如:

1.Tupleize();
// single
3.Tupleize();
// triple
100.Tupleize();
// centuple

數字1-10、100和1000將轉換為“命名”元組(即“單”,“雙”等), 任何其他數字“ n”將轉換為“ n元組”,

 

Humanizer 混合到您的框架中以簡化您的生活

這只是一個基礎,您可以使用它來簡化您的日常作業, 例如,在Asp.Net MVC中,我們一直在ViewModel屬性上保留Display屬性,以便HtmlHelper可以為我們生成正確的標簽, 但是,就像列舉一樣,在大多數情況下,我們只需要在屬性名稱中的單詞之間留一個空格-那么為什么不使用“ string” .Humanize呢?

您可能會在執行該操作的代碼中找到一個Asp.Net MVC示例(盡管該專案已從解決方案檔案中排除,從而使nuget包也可用于.Net 3.5),

這是通過使用名為HumanizerMetadataProvider的自定義DataAnnotationsModelMetadataProvider實作的, 它足夠小,可以在這里重復; 所以我們開始:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using Humanizer;

namespace YourApp
{
    public class HumanizerMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes,
            Type containerType,
            Func<object> modelAccessor,
            Type modelType,
            string propertyName)
        {
            var propertyAttributes = attributes.ToList();
            var modelMetadata = https://www.cnblogs.com/88223100/p/base.CreateMetadata(propertyAttributes, containerType, modelAccessor, modelType, propertyName);

            if (IsTransformRequired(modelMetadata, propertyAttributes))
                modelMetadata.DisplayName = modelMetadata.PropertyName.Humanize();

            return modelMetadata;
        }

        private static bool IsTransformRequired(ModelMetadata modelMetadata, IList<Attribute> propertyAttributes)
        {
            if (string.IsNullOrEmpty(modelMetadata.PropertyName))
                return false;

            if (propertyAttributes.OfType<DisplayNameAttribute>().Any())
                return false;

            if (propertyAttributes.OfType<DisplayAttribute>().Any())
                return false;

            return true;
        }
    }
}

此類呼叫基類以提取元資料,然后根據需要使屬性名稱人性化, 它正在檢查屬性是否已經具有DisplayName或Display屬性,在這種情況下,元資料提供程式將僅接受該屬性,而保留該屬性, 對于其他屬性,它將人性化屬性名稱, 就這些,

現在,您需要使用Asp.Net MVC注冊該元資料提供程式, 確保使用System.Web.Mvc.ModelMetadataProviders,而不使用System.Web.ModelBinding.ModelMetadataProviders:

ModelMetadataProviders.Current = new HumanizerMetadataProvider();

...現在您可以替換:

public class RegisterModel
{
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Display(Name = "Email address")]
    public string EmailAddress { get; set; }

    [Display(Name = "Confirm password")]
    public string ConfirmPassword { get; set; }
}

public class RegisterModel
{
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
    public string ConfirmPassword { get; set; }
}

 

...,“元資料人性化工具”將負責其余的作業,

無需提及,如果您想為標簽加上標題框,則可以使用Transform鏈接方法:

modelMetadata.DisplayName = modelMetadata.PropertyName.Humanize().Transform(To.TitleCase);

 

已知的安裝問題和解決方法

由于CLI工具中的錯誤,主要的Humanizer軟體包及其語言軟體包將無法安裝, 作為臨時解決方法,在修復該錯誤之前,請改用Humanizer.xproj, 它包含所有語言,

 

 

GitHub地址:https://github.com/Humanizr/Humanizer

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/59596.html

標籤:C#

上一篇:TripleDESCryptoServiceProvider CryptoStream

下一篇:.NET 基礎知識

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more