खोज…


फंक और एक्शन

फंक पैरामीटर अनाम कार्यों के लिए एक धारक प्रदान करता है। अग्रणी प्रकार इनपुट हैं और अंतिम प्रकार हमेशा रिटर्न मान होता है।

// square a number.
Func<double, double> square = (x) => { return x * x; };

// get the square root.
// note how the signature matches the built in method.
Func<double, double> squareroot = Math.Sqrt;

// provide your workings.
Func<double, double, string> workings = (x, y) => 
    string.Format("The square of {0} is {1}.", x, square(y))

एक्शन ऑब्जेक्ट्स शून्य विधियों की तरह होते हैं, इसलिए उनमें केवल एक इनपुट प्रकार होता है। मूल्यांकन स्टैक पर कोई परिणाम नहीं दिया गया है।

// right-angled triangle.
class Triangle
{
    public double a;
    public double b;
    public double h;
}

// Pythagorean theorem.
Action<Triangle> pythagoras = (x) => 
    x.h = squareroot(square(x.a) + square(x.b));

Triangle t = new Triangle { a = 3, b = 4 };
pythagoras(t);
Console.WriteLine(t.h); // 5.

अचल स्थिति

अपरिवर्तनीयता कार्यात्मक प्रोग्रामिंग में आम है और ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग में दुर्लभ है।

उदाहरण के लिए, परिवर्तनशील स्थिति के साथ एक पता प्रकार बनाएं:

public class Address () 
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City  { get; set; }
}

उपरोक्त वस्तु में कोई भी कोड किसी भी संपत्ति को बदल सकता है।

अब अपरिवर्तनीय पता प्रकार बनाएँ:

public class Address () 
{
    public readonly string Line1;
    public readonly string Line2;
    public readonly string City;

    public Address(string line1, string line2, string city) 
    {
        Line1 = line1;
        Line2 = line2;
        City  = city;
    }
}

इस बात को ध्यान में रखें कि केवल संग्रह के पढ़ने से अपरिवर्तनीयता का सम्मान नहीं होता है। उदाहरण के लिए,

public class Classroom
{
    public readonly List<Student> Students;
    
    public Classroom(List<Student> students)
    {
        Students = students;
    }
}

अपरिवर्तनीय नहीं है, क्योंकि ऑब्जेक्ट का उपयोगकर्ता संग्रह को बदल सकता है (इसमें से तत्वों को जोड़ या हटा सकता है)। इसे अपरिवर्तनीय बनाने के लिए, किसी को IEnumerable जैसे इंटरफ़ेस का उपयोग करना होगा, जो जोड़ने के तरीकों को उजागर नहीं करता है, या इसे ReadOnlyCollection बनाने के लिए।

public class Classroom
{
    public readonly ReadOnlyCollection<Student> Students;

    public Classroom(ReadOnlyCollection<Student> students)
    {
        Students = students;
    }
}

List<Students> list = new List<Student>();
// add students
Classroom c = new Classroom(list.AsReadOnly());   

अपरिवर्तनीय वस्तु के साथ हमारे निम्नलिखित लाभ हैं:

  • यह एक ज्ञात स्थिति में होगा (अन्य कोड इसे बदल नहीं सकते हैं)।
  • यह धागा सुरक्षित है।
  • निर्माणकर्ता सत्यापन के लिए एकल स्थान प्रदान करता है।
  • यह जानते हुए कि वस्तु को बदला नहीं जा सकता, कोड को समझना आसान बनाता है।

अशक्त संदर्भों से बचें

सी # डेवलपर्स से निपटने के लिए बहुत सारे शून्य संदर्भ अपवाद मिलते हैं। F # डेवलपर्स नहीं है क्योंकि उनके पास विकल्प प्रकार है। एक विकल्प <> प्रकार (कुछ पसंद करते हैं शायद <> एक नाम के रूप में) कुछ प्रदान करता है और एक वापस नहीं प्रकार। यह स्पष्ट करता है कि एक विधि अशक्त रिकॉर्ड वापस करने के लिए हो सकती है।

उदाहरण के लिए, आप निम्नलिखित नहीं पढ़ सकते हैं और जान सकते हैं कि क्या आपको एक अशक्त मूल्य से निपटना होगा।

var user = _repository.GetUser(id);

यदि आप संभावित अशक्त के बारे में जानते हैं तो आप इससे निपटने के लिए कुछ बॉयलरप्लेट कोड पेश कर सकते हैं।

var username = user != null ? user.Name : string.Empty;

अगर हमारे पास कोई विकल्प है तो क्या होगा?

Option<User> maybeUser = _repository.GetUser(id);

कोड अब यह स्पष्ट कर देता है कि हमारे पास कोई भी रिकॉर्ड वापस नहीं आया है और बॉयलरप्लेट कोड को कुछ या किसी के लिए जाँचने की आवश्यकता नहीं है:

var username = maybeUser.HasValue ? maybeUser.Value.Name : string.Empty;

निम्न विधि से पता चलता है कि विकल्प <> कैसे वापस किया जाए

public Option<User> GetUser(int id)
{
    var users = new List<User>
    {
        new User { Id = 1, Name = "Joe Bloggs" },
        new User { Id = 2, Name = "John Smith" }
    };

    var user = users.FirstOrDefault(user => user.Id == id);

    return user != null ? new Option<User>(user) : new Option<User>();
}

यहां विकल्प <> का न्यूनतम कार्यान्वयन है।

public struct Option<T>
{
    private readonly T _value;

    public T Value
    {
        get
        {
            if (!HasValue)
                throw new InvalidOperationException();

            return _value;
        }
    }

    public bool HasValue
    {
        get { return _value != null; }
    }

    public Option(T value)
    {
        _value = value;
    }

    public static implicit operator Option<T>(T value)
    {
        return new Option<T>(value);
    }
}

उपरोक्त avoidNull.csx प्रदर्शित करने के लिए C # REPL के साथ चलाया जा सकता है।

जैसा कि कहा गया है, यह एक न्यूनतम कार्यान्वयन है। "शायद" नूगेट पैकेज की खोज कई अच्छे पुस्तकालयों को बदल देगी।

उच्च-क्रम के कार्य

उच्च-क्रम फ़ंक्शन वह है जो किसी अन्य फ़ंक्शन को तर्क के रूप में लेता है या फ़ंक्शन (या दोनों) लौटाता है।

यह आमतौर पर लैम्ब्डा के साथ किया जाता है, उदाहरण के लिए जब एक LINQ के लिए एक विधेय पारित करते हैं जहां खंड:

var results = data.Where(p => p.Items == 0);

कहाँ () खंड कई अलग-अलग विधेय प्राप्त कर सकता है जो इसे काफी लचीलापन देता है।

किसी अन्य विधि में एक विधि पारित करना भी रणनीति डिजाइन पैटर्न को लागू करते समय देखा जाता है। उदाहरण के लिए, विभिन्न छंटाई विधियों को रन-टाइम पर आवश्यकताओं के आधार पर किसी ऑब्जेक्ट पर एक सॉर्ट विधि से चुना और पास किया जा सकता है।

अपरिवर्तनीय संग्रह

System.Collections.Immutable NuGet पैकेज अपरिवर्तनीय संग्रह कक्षाएं प्रदान करता है।

आइटम बनाना और जोड़ना

var stack = ImmutableStack.Create<int>();
var stack2 = stack.Push(1); // stack is still empty, stack2 contains 1
var stack3 = stack.Push(2); // stack2 still contains only one, stack3 has 2, 1

बिल्डर का उपयोग कर बनाना

कुछ अपरिवर्तनीय संग्रह में एक Builder आंतरिक वर्ग होता है जिसका उपयोग सस्ते में बड़े अपरिवर्तनीय उदाहरणों को बनाने के लिए किया जा सकता है:

var builder = ImmutableList.CreateBuilder<int>(); // returns ImmutableList.Builder
builder.Add(1);
builder.Add(2);
var list = builder.ToImmutable();

एक मौजूदा IEnumerable से बनाना

var numbers = Enumerable.Range(1, 5);
var list = ImmutableList.CreateRange<int>(numbers);

सभी अपरिवर्तनीय संग्रह प्रकारों की सूची:



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow