Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Definicje treści wyrażeń umożliwiają podanie implementacji elementu członkowskiego w zwięzłym, czytelnym formularzu. Definicję treści wyrażenia można użyć za każdym razem, gdy logika dla dowolnego obsługiwanego elementu członkowskiego, takiego jak metoda lub właściwość, składa się z pojedynczego wyrażenia. Definicja treści wyrażenia ma następującą ogólną składnię:
member => expression;
gdzie wyrażenie jest prawidłowym wyrażeniem .
Definicje treści wyrażeń mogą być używane z następującymi elementami członkowskimi typu:
Metody
Metoda typu wyrażenie-bodied składa się z pojedynczego wyrażenia, które zwraca wartość, której typ pasuje do typu zwracanego metody, lub dla metod, które zwracają voidmetodę , która wykonuje jakąś operację. Na przykład typy, które zastępują ToString metodę, zwykle zawierają pojedyncze wyrażenie, które zwraca reprezentację ciągu bieżącego obiektu.
W poniższym przykładzie zdefiniowano klasę, która zastępuje Person metodę ToString definicją treści wyrażenia. Definiuje również metodę DisplayName , która wyświetla nazwę konsoli. Ponadto zawiera kilka metod, które przyjmują parametry, pokazując, jak elementy członkowskie wyrażeń działają z parametrami metody. Słowo return kluczowe nie jest używane w żadnej z definicji treści wyrażeń.
using System;
namespace ExpressionBodiedMembers;
public class Person
{
public Person(string firstName, string lastName)
{
fname = firstName;
lname = lastName;
}
private string fname;
private string lname;
public override string ToString() => $"{fname} {lname}".Trim();
public void DisplayName() => Console.WriteLine(ToString());
// Expression-bodied methods with parameters
public string GetFullName(string title) => $"{title} {fname} {lname}";
public int CalculateAge(int birthYear) => DateTime.Now.Year - birthYear;
public bool IsOlderThan(int age) => CalculateAge(1990) > age;
public string FormatName(string format) => format.Replace("{first}", fname).Replace("{last}", lname);
}
class Example
{
public static void Main()
{
Person p = new Person("Mandy", "Dejesus");
Console.WriteLine(p);
p.DisplayName();
// Examples with parameters
Console.WriteLine(p.GetFullName("Dr."));
Console.WriteLine($"Age: {p.CalculateAge(1990)}");
Console.WriteLine($"Is older than 25: {p.IsOlderThan(25)}");
Console.WriteLine(p.FormatName("Last: {last}, First: {first}"));
}
}
Aby uzyskać więcej informacji, zobacz Metody (Przewodnik programowania w języku C#).
Właściwości tylko do odczytu
Aby zaimplementować właściwość tylko do odczytu, można użyć definicji treści wyrażenia. W tym celu użyj następującej składni:
PropertyType PropertyName => expression;
W poniższym przykładzie zdefiniowano klasę Location , której właściwość tylko Name do odczytu jest implementowana jako definicja treści wyrażenia zwracająca wartość pola prywatnego locationName :
public class Location
{
private string locationName;
public Location(string name)
{
locationName = name;
}
public string Name => locationName;
}
Aby uzyskać więcej informacji na temat właściwości, zobacz Właściwości (Przewodnik programowania w języku C#).
Właściwości
Definicje treści wyrażeń umożliwiają implementowanie właściwości get i set metod dostępu. W poniższym przykładzie pokazano, jak to zrobić:
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
// Example with multiple parameters
public class Point
{
public double X { get; }
public double Y { get; }
// Constructor with multiple parameters
public Point(double x, double y) => (X, Y) = (x, y);
// Constructor with single parameter (creates point at origin on axis)
public Point(double coordinate) => (X, Y) = (coordinate, 0);
}
Aby uzyskać więcej informacji na temat właściwości, zobacz Właściwości (Przewodnik programowania w języku C#).
Zdarzenia
Podobnie zdarzenia add i remove metody dostępu mogą być wyrażeń ciała:
public class ChangedEventArgs : EventArgs
{
public required int NewValue { get; init; }
}
public class ObservableNum(int _value)
{
public event EventHandler<ChangedEventArgs> ChangedGeneric = default!;
public event EventHandler Changed
{
// Note that, while this is syntactically valid, it won't work as expected because it's creating a new delegate object with each call.
add => ChangedGeneric += (sender, args) => value(sender, args);
remove => ChangedGeneric -= (sender, args) => value(sender, args);
}
public int Value
{
get => _value;
set => ChangedGeneric?.Invoke(this, new() { NewValue = (_value = value) });
}
}
Aby uzyskać więcej informacji na temat zdarzeń, zobacz Zdarzenia (Przewodnik programowania w języku C#).
Konstruktory
Definicja treści wyrażenia dla konstruktora zwykle składa się z pojedynczego wyrażenia przypisania lub wywołania metody, które obsługuje argumenty konstruktora lub inicjuje stan wystąpienia.
W poniższym przykładzie zdefiniowano klasęLocation, której konstruktor ma jeden parametr ciągu o nazwie name. Definicja treści wyrażenia przypisuje argument do Name właściwości . W przykładzie pokazano również klasę Point z konstruktorami, które przyjmują wiele parametrów, pokazując, w jaki sposób konstruktory wyrażeń współdziałają z różnymi kombinacjami parametrów.
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
// Example with multiple parameters
public class Point
{
public double X { get; }
public double Y { get; }
// Constructor with multiple parameters
public Point(double x, double y) => (X, Y) = (x, y);
// Constructor with single parameter (creates point at origin on axis)
public Point(double coordinate) => (X, Y) = (coordinate, 0);
}
Aby uzyskać więcej informacji, zobacz Konstruktory (Przewodnik programowania w języku C#).
Finalizatory
Definicja treści wyrażenia dla finalizatora zwykle zawiera instrukcje oczyszczania, takie jak instrukcje zwalniające niezarządzane zasoby.
W poniższym przykładzie zdefiniowano finalizator, który używa definicji treści wyrażenia, aby wskazać, że finalizator został wywołany.
public class Destroyer
{
public override string ToString() => GetType().Name;
~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}
Aby uzyskać więcej informacji, zobacz Finalizers (Przewodnik programowania w języku C#).
Indexers (Indeksatory)
Podobnie jak w przypadku właściwości, indeksator get i set metody dostępu składają się z definicji treści wyrażenia, jeśli get akcesor składa się z pojedynczego wyrażenia zwracającego wartość lub set akcesor wykonuje proste przypisanie.
W poniższym przykładzie zdefiniowano klasę o nazwie Sports , która zawiera tablicę wewnętrzną String zawierającą nazwy niektórych dyscyplin sportowych. Zarówno indeksator get , jak i set metody dostępu są implementowane jako definicje treści wyrażeń.
using System;
using System.Collections.Generic;
namespace SportsExample;
public class Sports
{
private string[] types = [ "Baseball", "Basketball", "Football",
"Hockey", "Soccer", "Tennis",
"Volleyball" ];
public string this[int i]
{
get => types[i];
set => types[i] = value;
}
}
Aby uzyskać więcej informacji, zobacz Indeksatory (Przewodnik programowania w języku C#).