検索
ホームページバックエンド開発C#.Net チュートリアルC# 関数型プログラミングのサンプル コードの詳細な紹介

関数型プログラミングについて言及するとき、誰もが非常に柔軟で動的な構文を備えた LISP や Haskell などの古代の関数型言語を思い浮かべるはずです。最近では、Ruby、JavaScript、F# も関数型プログラミングで人気の言語です。ただし、.net はラムダ式をサポートしているため、C# は命令型プログラミング言語ではありますが、関数型プログラミングにおいては劣りません。 C# でコードを記述するプロセスでは、高階関数、結合関数、純粋関数キャッシュなどのアイデアを意図的または意図せずに使用します。式ツリーなどのアイデアも、関数型プログラミングのアイデアから生まれています。次に、一般的に使用される関数型プログラミングのシナリオをまとめます。これは、プログラミング プロセスにこれらのテクノロジを柔軟に適用し、設計のアイデアを拡張し、コードの品質を向上させるのに役立ちます。

1. 高階関数

平たく言えば、高階関数: 関数をパラメータとして使用する関数は、高階関数と呼ばれます。この定義によれば、LINQ 式、Where、Select、SelectMany、First および .net で広く使用されているその他のメソッドはすべて高階関数です。では、独自のコードを作成するときにこの設計をいつ使用するのでしょうか。

例: 不動産手数料を計算する関数、var Fee=square*price を設計します。面積 (平方) は、不動産の性質に応じてさまざまな方法で計算されます。民間住宅、商業住宅などにはさまざまな係数を掛ける必要があります。そのようなニーズに応じて、次の関数を設計しようとします:

住宅地:

rreee

商業地域および住宅地域:

public Func<int,int,decimal> SquareForCivil()
{
    return (width,hight)=>width*hight;
}

これらの関数はすべて、Func という共通のシグネチャを持っているため、この関数シグネチャを使用して、不動産料金を計算する関数を設計できます:

public Func<int, int, decimal> SquareForBusiness()
{
    return (width, hight) => width * hight*1.2m;
}

テストを書いて見てください

rree

2. 遅延評価

C# は実行時に厳密な評価戦略を使用します。いわゆる厳密な評価とは、パラメーターが関数に渡される前に評価されることを意味します。この説明ではまだ少し分かりにくいでしょうか?シナリオを見てみましょう。実行する必要があるタスクがあり、そのためには現在のメモリ使用量が 80% 未満であり、前の計算の結果が 100 未満である必要があります。この条件は、タスクを実行する前に満たすことができます。実行されました。

この要件を満たす C# コードをすぐに書くことができます:

public decimal PropertyFee(decimal price,int width,int hight, Func<int, int, decimal> square)
{
    return price*square(width, hight);
}

NextStep を実行するときは、メモリ使用量と最初のステップ (関数 BigCalculationForFirstStep) の計算結果を渡す必要があります。コードに示されているように、最初のステップの操作は非常に時間がかかりますが、これは厳密な評価戦略のためです。 C# の for ステートメント If (memoryUtilization

したがって、遅延評価とは、結果が実際に必要な場合にのみ式または式の一部が評価されることを意味します。高階関数を使用してこの要件を書き直そうとします:

[Test]
public void Should_calculate_propertyFee_for_two_area()
{
    //Arrange
    var calculator = new PropertyFeeCalculator();
    //Act
    var feeForBusiness= calculator.PropertyFee(2m,2, 2, calculator.SquareForBusiness());
    var feeForCivil = calculator.PropertyFee(1m, 2, 2, calculator.SquareForCivil());
    //Assert
    feeForBusiness.Should().Be(9.6m);
    feeForCivil.Should().Be(4m);
}

コードは非常に単純で、関数式を使用して関数の値を置き換えるだけです。 if (memoryUtilization() クラスでは、このようなニーズがあるシナリオでこのメカニズムを使用できます

。 3. ファンクションカレー

カリー化は部分適用とも呼ばれます。定義: 複数のパラメーターを受け入れる関数を 1 つのパラメーター (元の関数の最初のパラメーター) を受け入れる関数に変換し、残りのパラメーターを受け入れて結果を返す新しい関数を返すテクノロジーです。 PS: なぜですか。公式の説明はそんなにわかりにくいですか?

このような定義を見ると、おそらく誰もがこれが何なのかを理解するのは難しいでしょう。それでは、カレーの原理から始めましょう:

2 つの数値を加算する関数を作成します:

public double MemoryUtilization()
 {
     //计算目前内存使用率
     var pcInfo = new ComputerInfo();
     var usedMem = pcInfo.TotalPhysicalMemory - pcInfo.AvailablePhysicalMemory; 
     return (double)(usedMem / Convert.ToDecimal(pcInfo.TotalPhysicalMemory));
 }
 
 public int BigCalculatationForFirstStep()
 {
     //第一步运算
     System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
     Console.WriteLine("big calulation");
     FirstStepExecuted = true;
     return 10;
 }
 
 public void NextStep(double memoryUtilization,int firstStepDistance)
 {
//下一步运算
     if(memoryUtilization<0.8&&firstStepDistance<100)
     {
         Console.WriteLine("Next step");
     }
 }

さて、この機能はどうやって使うのでしょうか?

りー

1+2=3、呼び出しは非常に簡単です。要件をアップグレードするには、パラメーター (数値) の入力を必要とし、10 + 入力パラメーター (数値) の結果を計算する関数が必要です。最初のパラメータとして 10 を渡せば、上記のコードはこの要件を完全に達成できる、と誰かが言うと思いますが、そう思うなら、私は何もする必要はありません。別のオーバーロードを記述するにはパラメータが 1 つだけ必要だと言う人もいるかもしれませんが、実際には他の人が提供する API を呼び出しているため、オーバーロードを追加することはできません。部分アプリケーションの使用シナリオはあまり一般的なシナリオではないことがわかります。そのため、最適な設計は、適切なシーンに適切なテクノロジーを適合させることです。部分アプリケーションの実装を見てみましょう:

public void NextStepWithOrderFunction(Func<double> memoryUtilization,Func<int> firstStep)
{
    if (memoryUtilization() < 0.8 && firstStep() < 100)
    {
        Console.WriteLine("Next step");
    }
}

式 x => y => int 型の関数によって取得される関数シグネチャ。この時点でもう一度電話する場合:

//Act
var curringResult = curringReasoning.AddTwoNumberCurrying()(10);
var result = curringResult(2);
 
//Assert
result.Should().Be(12);

  这句话:var curringResult = curringReasoning.AddTwoNumberCurrying()(10); 生成的函数就是只接收一个参数(number),且可以计算出10+number的函数。

  同样的道理,三个数相加的函数:

public Func<int,int,int,int> AddThreeNumber()
{
    return (x, y, z) => x + y + z;
}

  局部套用版本:

public Func<int,Func<int,Func<int,int>>> AddThreeNumberCurrying()
{
    Func<int, Func<int, Func<int, int>>> addCurring = x => y => z => x + y + z;
    return addCurring;
}

  调用过程:

[Test]
public void Three_number_add_test()
{
    //Arrange
    var curringReasoning = new CurryingReasoning();
 
    //Act
    var result1 = curringReasoning.AddThreeNumber()(1, 2, 3);
    var curringResult = curringReasoning.AddThreeNumberCurrying()(1);
    var curringResult2 = curringResult(2);
    var result2 = curringResult2(3);
    
    //Assert
    result1.Should().Be(6);
    result2.Should().Be(6);
}

  当函数参数多了之后,手动局部套用越来越不容易写,我们可以利用扩展方法自动局部套用:

public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
{
    return x => y => func(x, y);
}
 
public static Func<T1, Func<T2, Func<T3, TResult>>> Curry<T1, T2, T3, TResult>(this Func<T1, T2, T3,TResult> func)
{
    return x => y => z=>func(x, y,z);
}

  同样的道理,Action签名的函数也可以自动套用

  有了这些扩展方法,使用局部套用的时候就更加easy了

[Test]
public void Should_auto_curry_two_number_add_function()
{
    //Arrange
    var add = _curringReasoning.AddTwoNumber();
    var addCurrying = add.Curry();
 
    //Act
    var result = addCurrying(1)(2);
 
    //Assert
    result.Should().Be(3);
}

  好了,局部套用就说到这里,stackoverflow有几篇关于currying使用的场景和定义的文章,大家可以继续了解。

  函数式编程还有一些重要的思想,例如:纯函数的缓存,所为纯函数是指函数的调用不受外界的影响,相同的参数调用得到的值始终是相同的。尾递归,单子,代码即数据(.net中的表达式树),部分应用,组合函数,这些思想有的我也仍然在学习中,有的还在思考其最佳使用场景,所以不再总结,如果哪天领会了其思想会补充。

  四、设计案例

  最后我还是想设计一个场景,把高阶函数,lambda表达式,泛型方法结合在一起,我之所以设计这样的例子是因为现在很多的框架,开源的项目都有类似的写法,也正是因为各种技术和思想结合在一起,才有了极富有表达力并且非常优雅的代码。

  需求:设计一个单词查找器,该查找器可以查找某个传入的model的某些字段是否包含某个单词,由于不同的model具有不同的字段,所以该查找需要配置,并且可以充分利用vs的智能提示。

  这个功能其实就两个方法:

private readonly List<Func<string, bool>> _conditions; 
 
public WordFinder<TModel> Find<TProperty>(Func<TModel,TProperty> expression)
{
    Func<string, bool> searchCondition = word => expression(_model).ToString().Split(&#39; &#39;).Contains(word);
    _conditions.Add(searchCondition);
    return this;
}
 
public bool Execute(string wordList)
{
    return _conditions.Any(x=>x(wordList));
}

  使用:

[Test]
public void Should_find_a_word()
{
    //Arrange
    var article = new Article()
    {
        Title = "this is a title",
        Content = "this is content",
        Comment = "this is comment",
        Author = "this is author"
    };
 
    //Act
    var result = Finder.For(article)
        .Find(x => x.Title)
        .Find(x => x.Content)
        .Find(x => x.Comment)
        .Find(x => x.Author)
        .Execute( "content");
 
    //Assert
    result.Should().Be(true);
}

  该案例本身不具有实用性,但是大家可以看到,正是各种技术的综合应用才设计出极具语义的api, 如果函数参数改为Expression> 类型,我们还可以读取到具体的属性名称等信息。

以上がC# 関数型プログラミングのサンプル コードの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
C#.NET開発今日:トレンドとベストプラクティスC#.NET開発今日:トレンドとベストプラクティスApr 28, 2025 am 12:25 AM

C#.NET開発における最新の開発とベストプラクティスには、次のものが含まれます。1。非同期プログラミングは、アプリケーションの応答性を向上させ、Asyncを使用して非ブロッキングコードを簡素化し、キーワードを待ちます。 2。LINQは強力なクエリ関数を提供し、遅延した実行および式ツリーを介してデータを効率的に操作します。 3.パフォーマンスの最適化の提案には、非同期プログラミングの使用、LINQクエリの最適化、メモリの合理的な管理、コードの読みやすさとメンテナンスの改善、単体テストの書き込みが含まれます。

C#.NET:.NETエコシステムを使用したアプリケーションの構築C#.NET:.NETエコシステムを使用したアプリケーションの構築Apr 27, 2025 am 12:12 AM

.NETを使用してアプリケーションを構築する方法は? .NETを使用してアプリケーションを構築することは、次の手順を通じて達成できます。1)C#言語やクロスプラットフォーム開発サポートを含む.NETの基本を理解します。 2)コンポーネントや.NETエコシステムの作業原則などのコア概念を学習します。 3)単純なコンソールアプリケーションから複雑なWebAPISおよびデータベース操作まで、基本的および高度な使用をマスターします。 4)構成やデータベース接続の問題など、一般的なエラーとデバッグ手法に精通している。 5)アプリケーションのパフォーマンスの最適化と非同期プログラミングやキャッシュなどのベストプラクティス。

汎用性のある.NET言語としてのC#:アプリケーションと例汎用性のある.NET言語としてのC#:アプリケーションと例Apr 26, 2025 am 12:26 AM

C#は、エンタープライズレベルのアプリケーション、ゲーム開発、モバイルアプリケーション、Web開発で広く使用されています。 1)エンタープライズレベルのアプリケーションでは、C#がasp.netcoreにWebAPIを開発するためによく使用されます。 2)ゲーム開発では、C#がUnityエンジンと組み合わされて、ロールコントロールやその他の機能を実現します。 3)C#は、コードの柔軟性とアプリケーションのパフォーマンスを改善するために、多型と非同期プログラミングをサポートします。

Web、デスクトップ、モバイル開発用のC#.NETWeb、デスクトップ、モバイル開発用のC#.NETApr 25, 2025 am 12:01 AM

C#と.NETは、Web、デスクトップ、モバイル開発に適しています。 1)Web開発では、ASP.Netcoreがクロスプラットフォーム開発をサポートしています。 2)デスクトップ開発では、さまざまなニーズに適したWPFとWINFORMSを使用します。 3)モバイル開発は、Xamarinを介したクロスプラットフォームアプリケーションを実現します。

C#.NETエコシステム:フレームワーク、ライブラリ、およびツールC#.NETエコシステム:フレームワーク、ライブラリ、およびツールApr 24, 2025 am 12:02 AM

C#.NETエコシステムは、開発者がアプリケーションを効率的に構築できるようにするための豊富なフレームワークとライブラリを提供します。 1.ASP.NETCOREは、高性能Webアプリケーションの構築に使用されます。2.EntityFrameWorkCoreは、データベース操作に使用されます。これらのツールの使用とベストプラクティスを理解することにより、開発者はアプリケーションの品質とパフォーマンスを向上させることができます。

azure/awsへのc#.netアプリケーションの展開:ステップバイステップガイドazure/awsへのc#.netアプリケーションの展開:ステップバイステップガイドApr 23, 2025 am 12:06 AM

c#.netアプリをAzureまたはAWSに展開する方法は?答えは、AzureAppServiceとAwselasticBeanStalkを使用することです。 1。Azureでは、AzureAppServiceとAzurePipelinesを使用して展開を自動化します。 2。AWSでは、Amazon ElasticBeanstalkとAwslambdaを使用して、展開とサーバーレス計算を実装します。

C#.NET:強力なプログラミング言語の紹介C#.NET:強力なプログラミング言語の紹介Apr 22, 2025 am 12:04 AM

C#と.NETの組み合わせにより、開発者に強力なプログラミング環境を提供します。 1)C#は、多型と非同期プログラミングをサポートします。2).NETは、クロスプラットフォーム機能と同時処理メカニズムを提供し、デスクトップ、Web、モバイルアプリケーション開発で広く使用されています。

.NETフレームワーク対C#:用語のデコード.NETフレームワーク対C#:用語のデコードApr 21, 2025 am 12:05 AM

.NetFrameworkはソフトウェアフレームワークであり、C#はプログラミング言語です。 1..netframeworkは、デスクトップ、Web、モバイルアプリケーションの開発をサポートするライブラリとサービスを提供します。 2.C#は.NetFrameWork用に設計されており、最新のプログラミング機能をサポートしています。 3..NetFrameworkはCLRを介してコード実行を管理し、C#コードはILにコンパイルされ、CLRによって実行されます。 4. .NetFrameWorkを使用してアプリケーションをすばやく開発し、C#はLINQなどの高度な関数を提供します。 5.一般的なエラーには、タイプ変換と非同期プログラミングデッドロックが含まれます。 VisualStudioツールは、デバッグに必要です。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。