View Full Version : [C#] - Operator Overload su IEnumerable
Stavo cercando di arricchire la mia libreria di comandi Funzionali del C#.
A differenza del Python, non c'e' nativamente l'operatore + fra IEnumerable.
Esiste solo la function estension
Concat
Questo permetterebbe di scrivere cose tipo
ListA + ListB + ListC (e anche tutti gli altri derivati da IEnumerable di un qualsiasi tipo, compreso egli stesso)
invece che
ListA.Concat(ListB).Concat(ListC)
Ora, mi piacerebbe dotare la libreria dell'overload dell'operator+ sui tipi generici IEnumerable<T>, ovvero tutti quelli che vengono restituiti dagli operatori del LINQ.
Ci ho provato e non ci sono riuscito.
Ho cercato in giro e ho trovato un paragrafo sul libro
C# Cookbook
che farebbe proprio al caso mio
E' simile alla mia, almeno l'interfaccia
public static IEnumerable<T> operator +(IEnumerable<T> t1, IEnumerable<T> t2)
{
return t1.Concat(t2);
}
http://books.google.co.uk/books?id=74smyTz6dxUC&pg=PA350&lpg=PA350&dq=c%23+operator+on+ienumerable&source=web&ots=taB9Nycj57&sig=KEXET8fjHr6o9NehDKI30cbveAI&hl=en#PPA343,M1
Ma perche' non riesco a compilare ne la mia ne quella del libro?
^TiGeRShArK^
30-03-2008, 22:46
:boh:
così ad occhio mi pare corretta...
che errore ti dice?:confused:
Mi dice
One of the parameters of a binary operator must be the containing type
Il che non ha senso, non posso mettere la definizione dell'operatore nel file dove e' descritto IEnumerable.
Ho provato anche con le partial class ma non funziona.
^TiGeRShArK^
30-03-2008, 23:56
capito forse..
se guardi nell'esempio successivo nel link che hai postato si vede che implementa 3 volte l'operatore +:
1)operator + (Set<T>, Set<T>)
2)operator + (IEnumerable<T>, Set<T>)
3)operator + (Set<T>, IEnumerable<T>)
..quindi mi sa che il compilatore non accetta come parametri interfacce o classi astratte ma deve esserci almeno un parametro dello stesso tipo (concreto) in cui è definito l'overloading dell'operatore...
tieni conto però che la mia è solo una supposta però, eh :D
kernel::panic
31-03-2008, 08:41
Il che non ha senso, non posso mettere la definizione dell'operatore nel file dove e' descritto IEnumerable.
Ti obbliga a mettere la definizione all'interno della classe per un semplice motivo: se io ridefinissi l'operatore + tra interi (magari più volte in assembly differenti), quando scrivo 1+2 il compilatore quale definizione dovrebbe usare?
Col C# 3.x puoi provare con gli "extension methods" (anche se non so se possono essere applicati agli operatori):
http://visualcsharp.it/2008/02/20/c-30-extension-methods/
^TiGeRShArK^
31-03-2008, 08:56
Ti obbliga a mettere la definizione all'interno della classe per un semplice motivo: se io ridefinissi l'operatore + tra interi (magari più volte in assembly differenti), quando scrivo 1+2 il compilatore quale definizione dovrebbe usare?
Col C# 3.x puoi provare con gli "extension methods" (anche se non so se possono essere applicati agli operatori):
http://visualcsharp.it/2008/02/20/c-30-extension-methods/
ah ecco..
quindi il problema non è che non può essere un'interfaccia o una classe astratta ma è solo che deve essere definito all'interno dello stesso tipo di cui sta facendo l'overloading....
Ti obbliga a mettere la definizione all'interno della classe per un semplice motivo: se io ridefinissi l'operatore + tra interi (magari più volte in assembly differenti), quando scrivo 1+2 il compilatore quale definizione dovrebbe usare?
Non dovrebbe compilare.
Come quando fai l'overload di
operator+ (class A, class B)
all'interno di class A
e poi lo rifai all'interno di class B.
Col C# 3.x puoi provare con gli "extension methods" (anche se non so se possono essere applicati agli operatori):
http://visualcsharp.it/2008/02/20/c-30-extension-methods/
Avevo provato anche con questi. Non viene.
Ma allora l'esempio di quel libro? Hanno scritto una bufala?
Senza incasinarsi troppo sui template.
E' possibile definire un operator overload sulla classe base stringhe?
p.es:
static void string operator-(string A,string B)
{
// Codice che magari prendere tutti i caratteri di A
//a toglie i caratteri presenti in B
}
banryu79
31-03-2008, 09:48
Non dovrebbe compilare.
Come quando fai l'overload di
operator+ (class A, class B)
all'interno di class A
e poi lo rifai all'interno di class B.
Girando sul web ho trovato:
Some Tips while using Operator overloading:
1. While OverLoading a Operator always give public static access specifiers.
2. Operator Overloading should return a CLS type and not void.
3. Atleast one operand to the operator must be of type UDC [User Defined Class] because we cannot overload a operator with two int operands and perform subtraction for + operator which C# does not allow.
4. Relational Operators are overloaded in Pairs only.ie if == is overloaded then So !=.
5. Same Operator can be overloaded with different function signature for eg.
public static Matrix operator +(Matrix m1,int[,] m2)
{
}
we can also one more method like this:
public static Matrix operator + (Matrix m1,Matrix m2)
{
}
e questo
Binary operators perform an operation on two operands. At least one of the operands must be of the the enclosing struct or the class. This mechanism prevents you from redefining built in operators, for example, public static int operator +(int a, int b) {return a + b -1;} is not legal. An example of a binary operator is:
Qui c'è una pagina interessante -> link (http://blog.paranoidferret.com/?p=20)
Avevo provato anche con questi. Non viene.
Ma allora l'esempio di quel libro? Hanno scritto una bufala?
Ma in che classe andavano a ridefinire l'operatore?
kernel::panic
31-03-2008, 09:55
Non dovrebbe compilare.
Come quando fai l'overload di
operator+ (class A, class B)
all'interno di class A e poi lo rifai all'interno di class B.[/QUOTE]
Secondo me si sono tutelati nel caso in cui carichi dinamicamente un assembly in un AppDomain... l'assembly caricato potrebbe ridefinire un determinato operatore e questo a priori il compilatore non lo sa.
Grazie per intanto. Mi sa proprio che non si fa.
Ma in che classe andavano a ridefinire l'operatore?
E chi lo sa? Sembra un copia-incolla.
Con le extension ci si va molto vicini
public static IEnumerable<T> Aggiungili<T>(this IEnumerable<T> p1,
IEnumerable<T> p2)
{
foreach(T t in p1) yield return t;
foreach(T t in p2) yield return t;
// O qualsiasi altra cosa
}
Ma non si riesce a farlo con l'operator
public static IEnumerable<T> operator+<T>(this IEnumerable<T> p1,
IEnumerable<T> p2)
{
foreach(T t in p1) yield return t;
foreach(T t in p2) yield return t;
// O qualsiasi altra cosa
}
kernel::panic
31-03-2008, 10:00
Senza incasinarsi troppo sui template.
E' possibile definire un operator overload sulla classe base stringhe?
Mi sa di no... :cry:
^TiGeRShArK^
31-03-2008, 15:51
Grazie per intanto. Mi sa proprio che non si fa.
E chi lo sa? Sembra un copia-incolla.
Con le extension ci si va molto vicini
public static IEnumerable<T> Aggiungili<T>(this IEnumerable<T> p1,
IEnumerable<T> p2)
{
foreach(T t in p1) yield return t;
foreach(T t in p2) yield return t;
// O qualsiasi altra cosa
}
Ma non si riesce a farlo con l'operator
public static IEnumerable<T> operator+<T>(this IEnumerable<T> p1,
IEnumerable<T> p2)
{
foreach(T t in p1) yield return t;
foreach(T t in p2) yield return t;
// O qualsiasi altra cosa
}
ma così lo puoi fare se scrivi quel codice proprio nell'interfaccia IEnumerable (che, essendo un'interfaccia mi sa proprio che non si può fare :p).
Per String vale la stessa cosa.
Infatti nell'esempio che hai linkato tu poi l'hanno fatto all'interno della classe Set che hanno definito loro e hanno ridefinito i 3 operatori per i vari tipi.
Gia'.
Niente operator+ per tutti gli IEnumerator generici quindi.
Peccato.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.