Laden...

Problem mit Interface Implementierung

Erstellt von mrgraf vor 17 Jahren Letzter Beitrag vor 17 Jahren 1.889 Views
M
mrgraf Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren
Problem mit Interface Implementierung

Hallo zusammen,
ich habe bisher leider erfolglos versucht, ein Interface member zu implementieren und habe keine Idee mehr, was ich falsch mache.
Vielleicht kann mir jemand auf die Sprünge helfen ...

public class P3User : BaseObject, IUserWithRoles, IUser, IAuthenticationActiveDirectoryUser, IAuthenticationStandardUser {
        public P3User(Session session) : base(session) { }

        [Association("P3User-P3Role")]
        public XPCollection<P3Role> Roles {
            get { return GetCollection("Roles"); }
        }


public class P3Role : RoleBase, IRole {
        public P3Role(Session session) : base(session) { }

        [Association("P3User-P3Role")]
        public XPCollection<P3User> Users {
            get { return GetCollection("Users"); }
        }
    }

dabei möchte IRole den Member


IList<IUser> Users { get; }

implementiert haben und IUserWithRoles den Member


IList<IRole> Roles { get; }

Wobei XPCollection als Framework Klasse definiert ist als


XPCollection : XPBaseCollection

und XPBaseCollection als


XPBaseCollection : Component, ITypedList, ISupportInitialize, ISessionProvider, IDataLayerProvider, IXPDictionaryProvider, IObjectChange, IFilteredXtraBindingList, IBindingList, IList, ICollection, IEnumerable

All die anderen Interfaces Implementierungen die P3User hat, waren erfolgreich und funktionieren.

Die Fehlermeldung lautet natürlich
XAF_ERP.Module.P3Role" implementiert den Schnittstellenmember "IRole.Users" nicht. "P3Role.Users" ist statisch, nicht öffentlich oder hat den falschen Rückgabewert. D:\Visual Studio 2005

Hat jemand eine Idee?

Danke
Gruß
Thomas

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo mrgraf,

XAF_ERP.Module.P3Role" implementiert den Schnittstellenmember "IRole.Users" nicht. "P3Role.Users" ist statisch, nicht öffentlich oder hat den falschen Rückgabewert.

herbivore

M
mrgraf Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Habe ich dann möglicherweise ein generelles Verständnisproblem?

Wenn ein Interface Member


IList Names { get; }

implementiert werden muss, muss dann die Implementierung auch wirklich eine IList zurückgeben?

Mein Verständnis war bislang (ich gebe zu, mit Interfaces habe ich noch nicht wirklich viel zu tun gehabt), dass der Rückgabetyp zumindest IList implementieren muss!?
Daher mein Problem in diesem Fall.

Danke & Gruß

T
512 Beiträge seit 2006
vor 17 Jahren

Du kannst letztendlich jedes Objekt zurückgeben, was IList implementiert.

Aber die Signatur der Property in der Klasse muss mit der Signatur im Interface übereinstimmen. Das heißt der definierte Rückgabetyp muss identisch sein. Wenn im Interface IList als Rückgabetyp steht, muss auch die Property in der Klasse IList als Rückgabetyp definiert haben, egal welches Objekt am Ende tatsächlich zurückgegeben wird.

e.f.q.

Aus Falschem folgt Beliebiges

M
mrgraf Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Ok.
Danke, dann muss ich die Frage weiter an den Framework Anbieter richten, denn die haben


public interface IUserWithRoles : IUser {
        IList<IRole> Roles { get; }
}

public class User : Person, IUserWithRoles, IUser,   
   IAuthenticationActiveDirectoryUser, IAuthenticationStandardUser {
   
        [Association("User-Role")]
        public XPCollection<Role> Roles { get; }

usw. zu stehen. Zumindest kann ich das aus den Metadaten so lesen.

Das passt dann ja nicht so recht dazu.

Gruß
Thomas

R
494 Beiträge seit 2006
vor 17 Jahren

Wenn du Visual Studio 2005 benutzt kannst du dir die Implementierung der Interfaces von der IDE machen lassen und dann nur noch entsprechend mit sinnvollem Inhalt füllen.

T
512 Beiträge seit 2006
vor 17 Jahren

Ich könnte mir vorstellen, dass die Interfaces explizit implementiert wurden.
Also das Interface wurde explizit implementiert, und dann die Property mit dem "echten" Typ zusätzlich noch hinzugefügt. Die expliziten Implementierungen sieht man nur, wenn man auf das Interface castet.

Das sähe dann so aus:

public interface IUserWithRoles : IUser {
        IList<IRole> Roles { get; }
}

public class User : Person, IUserWithRoles, IUser,  
   IAuthenticationActiveDirectoryUser, IAuthenticationStandardUser {
  
        [Association("User-Role")]
        public XPCollection<Role> Roles
        {
                get { ... }
        }

        // keine Ahnung ob hier noch ein Attribut hin müsste...
        IList<IRole> IUserWithRoles.Roles
        {
                get { return this.Roles; }
        }

Das ist prinzipiell keine schlechte Idee. Man sollte das aber nur bei Rückgabetypen machen.

Ich möchte noch für herbivore anmerken, dass dieses Beispiel auch das einzige Szenario ist, bei dem man das new Schlüsselwort sinnvoll einsetzen könnte. In dem Fall wäre das Roles eine Property der Basisklasse und man würde das mit einem Roles mit spezielleren Typ verdecken. So sieht das z.B. bei allen von DbCommand erbenden Klassen und der Parameters Property aus.

Wie gesagt nur bei Typen von Rückgabewerten zu empfehlen.

e.f.q.

Aus Falschem folgt Beliebiges

M
mrgraf Themenstarter:in
7 Beiträge seit 2006
vor 17 Jahren

Thanks a lot!
Ich denke mein Verständnis für Interfaces hat sich wesentlich verbessert.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Traumzauberbaum,

ok, bei der Spezialisierung eines Rückgabetyps wäre new tatsächlich erwägenswert, m.E. allerdings nur dann, wenn die Implementierung folgendem Muster folgt:


new public SpeziellerTyp Methode ()
{
   return (SpeziellerTyp)base.Methode ();
}

herbivore