myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Template Klasse: "Operator "*" kann nicht auf Operanden vom Typ "T" und "T" angewendet werden"
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Template Klasse: "Operator "*" kann nicht auf Operanden vom Typ "T" und "T" angewendet werden"

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
rob_s
myCSharp.de-Mitglied

Dabei seit: 11.07.2015
Beiträge: 2


rob_s ist offline

Template Klasse: "Operator "*" kann nicht auf Operanden vom Typ "T" und "T" angewendet werden"

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi! Ich bin neu in c# und stolpere grade hieran:

C#-Code:
class MyVector3<T>
{
    public T x { get; set; }
    public T y { get; set; }
    public T z { get; set; }


    public static MyVector3<T> operator *(MyVector3<T> vec1, MyVector3<T> vec2)
    {
        return new MyVector3<T>(vec1.x * vec2.x, vec1.y * vec2.y, vec1.z * vec2.z);
    }
}

Fehlermeldung:
Fehler 37: Der Operator "*" kann nicht auf Operanden vom Typ "T" und "T" angewendet werden.

Ich hab jetzt mit

C#-Code:
class MyVector3<T> where T : IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>

alles hingepackt was mir dazu einfällt aber der Fehler ist immernoch da.
11.07.2015 14:39 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Palladin007 Palladin007 ist männlich
myCSharp.de-Mitglied

avatar-4140.png


Dabei seit: 03.02.2012
Beiträge: 1.325
Entwicklungsumgebung: Visual Studio 2019
Herkunft: NRW


Palladin007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es gibt diesen Operator für den Typ T nicht.
Den muss Du extra definieren, oder Du verwendest Typen, die ihn bereits haben, z.B. alle Zahlen-Typen.

Du wirst vermutlich nicht um eine Basisklasse für T herum kommen, wo Du dann deinen Operator definierst.
Siehe  Überladbare Operatoren

Viel interessanter ist aber die Frage:
Wozu brauchst Du Generics? Es sieht für mich aus, als würdest Du normale Zahlen brauchen, dann nimm doch einfach int, bzw. double?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am 11.07.2015 14:57.

11.07.2015 14:56 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.280
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Es ist hier nicht ersichtlich, was T ist.
Daher kann der Compiler hier auch keine Multiplikation durchführen.
11.07.2015 14:57 Beiträge des Benutzers | zu Buddylist hinzufügen
malignate
myCSharp.de-Mitglied

avatar-3206.png


Dabei seit: 18.02.2005
Beiträge: 742


malignate ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du kommst bestimmt von C++, dort werden die Templates vom Compiler auch nur als Templates genutzt und nur die konkreten Typen kompiliert, z.B. Vector<float>. In C# werden Generics aber zur Laufzeit aufgelöst und dann muss der Compiler eben die Rahmenbedingungen kennen.

Leider ist heir C# nicht mächtig genug.

EDIT: Wenn du sowas machen willst, würde ich einfach Code Generierung anwenden.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von malignate am 11.07.2015 15:04.

11.07.2015 15:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
rob_s
myCSharp.de-Mitglied

Dabei seit: 11.07.2015
Beiträge: 2

Themenstarter Thema begonnen von rob_s

rob_s ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Es sieht für mich aus, als würdest Du normale Zahlen brauchen, dann nimm doch einfach int, bzw. double?

tja ich wollte beides. einen Int-Vector und einen double-Vector.

*ächz* in c++ hätt ich die Klasse in 2 minuten abgetippt...

Zitat:
Es ist hier nicht ersichtlich, was T ist.

Deshalb das

C#-Code:
where

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von rob_s am 11.07.2015 15:16.

11.07.2015 15:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
malignate
myCSharp.de-Mitglied

avatar-3206.png


Dabei seit: 18.02.2005
Beiträge: 742


malignate ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das where (nennt sich constraints) würde grundsätzlich gehen, du könntest zum Beispiel Formulieren, dass alle T's bestimmte mathematische Operationen unterstützen müssen, ABER...

1) Es gibt keine passendes Interface
2) Interfaces können keine Operatoren haben

Beispielsweise:

C#-Code:
interface ISupportPlus<T>
{
   T Add(T other);
}

class Vector<T> where T : ISupportsPlus<T>
{
    T x, y, z;

    Vector<T> Add(Vector<T> other)
    {
        return new Vector<T>(x.Add(other.x), ...);
    }
}

Aber wie gesagt: Es geht einfach nicht :(

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von malignate am 11.07.2015 22:47.

11.07.2015 15:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
pdelvo pdelvo ist männlich
myCSharp.de-Mitglied

avatar-3354.png


Dabei seit: 02.11.2008
Beiträge: 1.346
Entwicklungsumgebung: Visual Studio 2012 Prof.


pdelvo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Entsprechende generic constraints sind aber aktuell im Gespräch um das in kommenden C# Versionen zu unterstützen. Aktuell geht das leider nicht nicht.
11.07.2015 19:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.280
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Also "es geht nicht" ist mal pauschal falsch :-)
Es geht, aber nur, wenn man auf Typsicherheit verzichtet und dynamic verwendet.
11.07.2015 19:55 Beiträge des Benutzers | zu Buddylist hinzufügen
FZelle
myCSharp.de-Poweruser/ Experte

Dabei seit: 23.04.2004
Beiträge: 9.853


FZelle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@malignate:

Zitat:
In C# werden Generics aber zur Laufzeit aufgelöst und dann muss der Compiler eben die Rahmenbedingungen kennen.

Stimmt nicht, denn dann würdest du nicht einen Compilerfehler bei dem Konstrukt erhalten sondern eine Exception zur Laufzeit.

Aber es wird nicht beim Compilieren des konkreten T geprüft, sondern beim compilieren der Generischen Implementierung.
12.07.2015 13:44 Beiträge des Benutzers | zu Buddylist hinzufügen
malignate
myCSharp.de-Mitglied

avatar-3206.png


Dabei seit: 18.02.2005
Beiträge: 742


malignate ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Vielleicht sind die Begriffe falsch, aber es passiert beides: Der Generic wird Type wird vom Compiler erzeugt und Informationen über alle Typparameter inklusive Constraints hinterlegt.

Deshalb ist es auch nicht möglich mit Reflection ungültigen Typen für die Parameter zu erzeugen.

In C++ sind das einfach zwei verschiedene Klassen.
12.07.2015 15:55 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ikaros
myCSharp.de-Mitglied

Dabei seit: 27.05.2005
Beiträge: 1.739


ikaros ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Law of Demeter.
Operatoren können nur für konkrete Klassen/Interfaces erzeugt werden.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ikaros am 12.07.2015 19:11.

12.07.2015 19:10 Beiträge des Benutzers | zu Buddylist hinzufügen
malignate
myCSharp.de-Mitglied

avatar-3206.png


Dabei seit: 18.02.2005
Beiträge: 742


malignate ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das ist einfache eine Design-Entscheidung gewesen:  Why are overloaded operators always static in C#?

Den Zusammenhang mit Law of Demeter sehe ich jetzt nicht.
12.07.2015 19:48 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ikaros
myCSharp.de-Mitglied

Dabei seit: 27.05.2005
Beiträge: 1.739


ikaros ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Law of Demeter: rede nicht mit Fremden.
Generische Klassen/ Interfaces implementieren nicht unbedingt die verlangten/benutzten Operatoren nach Definition,dieImplementation kann sehr willkürlich sein. Keine Garantie, kein Vertrag.
12.07.2015 19:55 Beiträge des Benutzers | zu Buddylist hinzufügen
malignate
myCSharp.de-Mitglied

avatar-3206.png


Dabei seit: 18.02.2005
Beiträge: 742


malignate ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich kapier es immer noch nicht. Operatoren sind in erster Linie nur syntaktischer Zucker. Allerdings sind die aus Gründen der Symmetrie statisch (siehe Link) und können deshalb nicht Teil von Interfaces sein. Law of Demeter sagt ja auch nicht: Rede mit Niemandem
12.07.2015 20:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ikaros
myCSharp.de-Mitglied

Dabei seit: 27.05.2005
Beiträge: 1.739


ikaros ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Mein Posting war auch sprachununabhängig.
Operatoren sind Funktionen.
Die Ausführung solcher, liefert zwar ein Ergebnis zurück....
Deshalb kann ein Operator kein Bestandteil einer generischen Klasse oder eines Interfaces sein.
Vermute mal, ich habe mich zuvor unverständlich ausgerdrückt.
12.07.2015 20:28 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 5 Jahre.
Der letzte Beitrag ist älter als 5 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 20.10.2020 07:57