Co zamiast funkcji zaprzyjaźnionych jest w c# ?
Bo jeśli chcę przeładować operator << dla jakiejś klasy w C++ to trzeba w klasie zamieścić deklarację przyjaźni z tą funkcją przeładowującą. A jak jest w c#?

- Rejestracja:prawie 14 lat
- Ostatnio:około 10 godzin
- Postów:525
O przeładowaniu operatorów jest wspomniane np. w dokumentacji na MSDN ;) https://msdn.microsoft.com/pl-pl/library/8edha89s.aspx
Po prostu dodajesz specyficzną funkcję statyczną w klasie.

- Rejestracja:prawie 14 lat
- Ostatnio:około 18 godzin
- Postów:2512
Przeładowanie operatorów ma swoje ograniczenia. Inaczej niż w C++ zrobisz tak obiekt > 1
, ale już nie zrobisz tak: 1 > obiekt
, ponieważ funkcja przeładowująca jest elementem składowym klasy. Przed przeładowywaniem operatorów trzeba się dobrze zastanowić czy aby na pewno jest to tobie potrzebne. Ja w praktyce zawodowej jeszcze przeładowania nie potrzebowałem.
- Rejestracja:ponad 9 lat
- Ostatnio:ponad 9 lat
- Postów:27
Mam klase zespolona. Definiuje funkcje globalna dodającą liczby zespoloną. W klasie zespolona część rzeczywista i urojona to dane prywatne. Aby funkcja globalna dodająca liczby zespole miała do nich dostęp muszę w klasie zespolona zadeklarować przyjaźń z tą funkcją. Jak by to wyglądało w c#?
- Rejestracja:prawie 11 lat
- Ostatnio:ponad 7 lat
- Postów:475
- Rejestracja:ponad 10 lat
- Ostatnio:7 miesięcy
- Postów:194
W c# zrobił bym tak :
Utworzył strukturę/klasę : Liczba zespolona
Klasa zawierała by dwa publiczne property : Część rzeczywistą oraz urojoną
Przeciążył bym operatory : + - * / etc (Operatory bez problemu miały by dostęp do elementów składowych poprzez publiczne property.)


- Rejestracja:ponad 11 lat
- Ostatnio:ponad 4 lata
- Postów:2442
Funkcje zaprzyjaźnione to twór, który łamie zasady enkapsulacji w programowaniu obiektowym. Nie po to ktoś robił składowe klasy jako prywatne, że był do nich dostęp. W C# nie tędy droga, bo C# to nie C++.
A przeładowywać operatory można za pomocą funkcji statycznych wewnątrz klasy, której to przeładowanie dotyczy. Bardzo ładnie jest to wytłumaczone na stronach MSDN.
using System;
public struct Complex
{
public int real;
public int imaginary;
public Complex(int real, int imaginary)
{
this.real = real;
this.imaginary = imaginary;
}
// Declare which operator to overload (+), the types
// that can be added (two Complex objects), and the
// return type (Complex):
public static Complex operator +(Complex c1, Complex c2)
{
return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
// Override the ToString method to display an complex number in the suitable format:
public override string ToString()
{
return(String.Format("{0} + {1}i", real, imaginary));
}
public static void Main()
{
Complex num1 = new Complex(2,3);
Complex num2 = new Complex(3,4);
// Add two Complex objects (num1 and num2) through the
// overloaded plus operator:
Complex sum = num1 + num2;
// Print the numbers and the sum using the overriden ToString method:
Console.WriteLine("First complex number: {0}",num1);
Console.WriteLine("Second complex number: {0}",num2);
Console.WriteLine("The sum of the two numbers: {0}",sum);
}
}
https://ideone.com/vFPy8v
https://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx - stąd też powyższy przykład
Resumując takim rzeczom jak friend
mówimy w C# stanowczo nie.
PS: Nie sugerować się tym, że składowe imaginary
oraz real
są publiczne. Równie dobrze można zamienić je na prywatne.

- Rejestracja:prawie 10 lat
- Ostatnio:4 miesiące
- Lokalizacja:Hong Kong
Sarrus napisał(a):
Przeładowanie operatorów ma swoje ograniczenia. Inaczej niż w C++ zrobisz tak
obiekt > 1
, ale już nie zrobisz tak:1 > obiekt
, ponieważ funkcja przeładowująca jest elementem składowym klasy.
nie do konca masz racje, albo cie nie zrozumialam:
using System;
public class Test
{
//calkiem przydatna klasa, kazda intancja jest wieksza od dowolnego inta :)
public sealed class C
{
public static bool operator<(C c, int i)
{
return false;
}
public static bool operator<(int i, C c)
{
return true;
}
public static bool operator>(C c, int i)
{
return true;
}
public static bool operator>(int i, C c)
{
return false;
}
}
public static void Main()
{
var c = new C();
Console.WriteLine(1 < c);
Console.WriteLine(1 > c);
Console.WriteLine(c < 1);
Console.WriteLine(c > 1);
}
}
Sarrus napisał(a):
Przed przeładowywaniem operatorów trzeba się dobrze zastanowić czy aby na pewno jest to tobie potrzebne. Ja w praktyce zawodowej jeszcze przeładowania nie potrzebowałem.
poza typami wbudowanymi mysle ze zarowno operatory jak i customowe konwersje wprowadzaja wiecej szkod niz realnej wartosci.
imo wprowadzenie selektywnego lamania enkapsulacji (lub jak niektorzy to nazywaja 'lepszej kontroli') byloby kompletnie zbedne, juz protected internal wydaje mi sie przerostem formy nad trescia ;) tak naprawde wprowadza to niepotrzebny zamet i prawie zawsze wynika to ze zlego zaplanowania relacji miedzy klasami