Warum ich (manchmal) zu Referenz-Assemblys verwiesen wird, die von der Versammlung auf die ich mich beziehe?
Habe ich eine Versammlung Ein, die definiert eine Schnittstelle mit einigen überladungen:
public interface ITransform
{
Point InverseTransform(Point point);
Rect InverseTransform(Rect value);
System.Drawing.Point InverseTransform(System.Drawing.Point point);
}
...und eine Baugruppe B, die auf Eine (die binären, nicht das Projekt), und ruft eine der überladungen:
var transform =
(other.Source.TransformToDisplay != null &&
other.Source.TransformToDisplay.Valid) ?
other.Source.TransformToDisplay : null;
if (transform != null)
{
e.Location = transform.InverseTransform(e.Location);
}
Um genau zu sein, es ruft die System.Windows.Point
überlastung der InverseTransform
Methode, denn das ist der Typ der Eigenschaft Location
im e
.
Aber wenn ich bauen B in der IDE bekomme ich:
Fehler CS0012: Der Typ 'System.Zeichnung.Punkt' defined in an assembly that is not referenced. Müssen Sie fügen Sie einen Verweis auf die assembly " System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
obwohl das auch nicht die überlastung rufe ich. Wenn ich den Kommentar aus der Zeile, wo die überladene Methode InverseTransform
heißt, es baut feines, obwohl ich bin immer noch der Instanziierung ein Objekt vom Typ ITransform
.
Warum? Und gibt es eine Möglichkeit dieses Problem zu beheben, ohne dass Sie einen Verweis auf System.Drawing
überall?
- Aus Neugier, könnten Sie benennen Sie die Letzte überladung
InverseTransform2
und versuchen Sie es erneut? Ich kenne die Antwort nicht, aber ich Frage mich, wenn es nichts zu tun hat mit überlast-Auflösung. - Ist
e.Location
speziell einSystem.Windows.Point
Objekt, oder einer anderen Klasse abgeleitet ausSystem.Windows.Point
? - ja, es hat zu tun mit überlast-Auflösung, die mit anderen Methodennamen löst es aber ich will nicht zu ändern Sie die Schnittstelle
- Morgan: e.Lage ist ein System.Windows.Punkt, und selbst wenn es abgeleitet, dass es immer eine System.Windows.Punkt und nie ein System.Zeichnung.Punkt
- Es kann von Bedeutung für den compiler; siehe mein Kommentar auf Slaks Antwort. Da der compiler nicht weiß, was ein
System.Drawing.Point
ist, weiß er nicht, was überlastung ist die spezifischee.Location
. AngenommenSystem.Drawing.Point
ist eine Schnittstelle, unde.Location
ist eine abgeleitete Klasse, die diese Schnittstelle implementiert? Damit wäre die zweite überladung der richtige verwenden. Funktioniert der compiler wissen, dasse.Location
wird immer einSystem.Windows.Point
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Muss der compiler wissen, was für ein
System.Drawing.Point
ist, um zu beweisen, dass es nicht der richtige überlastung (z.B., wenn es eine implizite Konvertierung).System.Drawing.Point InverseTransform(System.Drawing.Point point);
Auch wenn Sie eine Form haben, es muss noch wissen was für ein System.Zeichnung.Punkt ist.e.Location
ist bekannt, dass einSystem.Windows.Point
(und nicht eine Ableitung von, dass), dann gibt es keine MöglichkeitSystem.Drawing.Point
könnte die meisten spezifischen überlastung. Es wäre denkbar, überspringen, dass ein Teil der überlast Auflösung.Diese Methode macht Gebrauch von etwas definiert in
System.Drawing
. Wenn Sie kommentieren Sie es dann, dass die Montage nicht mehr, indem Sie versuchen, zu verwendenSystem.Drawing
; daher kein Erfordernis.Denken Sie an es auf diese Weise, wenn Sie gehen, um Ihre Aktion .NET sagt ok ich mache einen Anruf zu diesem Mann in dieser Versammlung und sucht den entsprechenden code ausführen. Sie können es nicht finden, so wirft er Sie in seine Hände und sagt ich gebe Sie mir sagen, wo es ist.
Nur machen Sie es eine Gewohnheit, die Referenz jeder DLL, die Sie möglicherweise verwenden.
Anstatt zu sagen, was Sie nicht tun können...
Eine Möglichkeit dieses Problem zu beheben würde bedeuten, die Einführung von IPoint-Transformation(IPoint x) als die einzige Methode in der Schnittstelle, zusammen mit IPoint-Schnittstelle. Dies würde bedeuten, dass System.Zeichnung zu erfüllen, um Ihre IPoint als gut.
Wenn Sie möchten, dass die Ebene der Entkopplung, dynamic-Schlüsselwort kommt in den Sinn, da kann man nicht die Zeichnung zu erhalten.Zeigen Sie eine Schnittstelle implementieren, nach-der-Tatsache. Nur sicher sein, wirklich tolle unit-test-Abdeckung auf diesen Teil des Codes, und erwarten, dass es zu etwas langsamer.
Diese Weise würde man nur zu Referenz-System.Zeichnung nur in Versammlungen, wo Sie Sie wirklich verwenden.
BEARBEITEN Reflektor, sagt, dass die Signatur-System.Zeichnung.Punkt ist
Der einzige Unterschied zwischen überlastungen sind die Typen. Das ist, warum der compiler nicht unterscheiden kann, die überlastung, die Sie verwenden, ohne auf den Typ.
Da der Typ nicht verwiesen wird, indem die Ausführung der Montage, der compiler kennt Sie nicht, die Art und braucht eine direkte Referenz auf die assembly mit der Typ-definition.
Lief ich in das Problem selbst und nicht möchten, fügen Sie einen direkten Verweis auf die assembly, die den Text enthält. Added mich einfach ein argument (boolean), um eine der Methoden, so dass Sie nicht mehr überladungen von einander. Der compiler dann verstehen Sie den Unterschied zwischen den Methoden, auch wenn Sie denselben Namen haben, denn Sie haben eine unterschiedliche Anzahl von Argumenten. Es nicht mehr erforderlich, einen Verweis auf die assembly, die den Text enthält. Ich weiß, es ist keine ideale Lösung, aber ich konnte nicht finden eine andere Lösung als meine Methode war ein Konstruktor, also ich konnte es nicht ändern, seine Unterschrift in anderer Weise.
Diese zu lösen (vorausgesetzt, Sie haben nicht zu viel fordert, zu wickeln etc.)
man könnte einfach definieren, eine Erweiterung wrapper für diesen "Point" nennen Sie nur mit z.B.
...feed, die lib (wobei sich die Erweiterung) des Systems.Zeichnung Referenz
(und um zu vermeiden, dass Sie Ihre 'wrapper-lib' steht überall, dass würde Niederlage der Zweck, setzen Sie ihn einfach in einigen common-lib die Sie verwiesen bereits auf das problem beziehen. Am besten ist, wenn ein Teil der 'Quelle' lib, aber zu sagen, falls Sie nicht mehr ändern)...
und rufen Sie dann über
MyInverseTransform
statt.