Gå til innhold

Anbefalte innlegg

Hei folkens. Interfaces i C# er litt annerledes en i Clarion. Noen som kan hjelpe meg litt med følgende.

 

Her er Clarions måte å bruker Interfaces på:

iMyInterface       INTERFACE
Metode1               PROCEDURE()
                  END

MyClass            CLASS, IMPLEMENTS(MyInterface)
iExternal             &iMyInterface

SomeMethod            PROCEDURE()
   CODE
   If (Something = 123)
       Self.iExternal.Metode1()
   End !If

iMyInterface.Metode1  PROCEDURE()
   CODE
   Message('Metode1 er kallet fra et eksternt objekt')

                   END !CLASS

Så kan jeg gjøre følgende:

Obj1                 MyClass
Obj2                 MyClass

Obj1.iExternal &= Obj2.iMyInterface
Obj2.iExternal &= Obj1.iMyInterface

Dermed har jeg to objekter av samme klasse, der objekt 1 refererer til interfaceet i objekt 2 og omvendt. Noe som fører til følgende at et kall til Obj1.SomeMethod() eller Obj2.SomeMethod() vil vise en message boks som sier at Metode1 er kallet fra et eksternt objekt.

 

Jeg prøver å få til tilsvarende i C#, men følgende virker ikke:

public iMyInterface INTERFACE
{
   void Metode1()
}

public class MyClass : iMyInterface
{
   iMyInterface iExternal;
....
}

Når jeg prøver å kalle mot iExternal så feiler det under kompillering. Jeg har skjønt at et interface i C# er en slags kontrakt som sier noe om hvilke metoder som må være tilstede, men jeg vil jo gjerne kunne sende interfaces videre til andre objekter for bruk.

 

All hjelp mottas med takk.

 

btw - jeg trenger dette fordi jeg lager en wrapper som lar meg samkjøre managen og unmanaged code og dermed blande programkode fra Clarion inn i C# og omvendt.

Lenke til kommentar
Videoannonse
Annonse

Et interface er en kontrakt ja, for å kreve at en datatype som konverteres til det interfacet implementerer alle funksjonene og egenskapene som er definert i interfacet.

Merk at du også kan bruke interfaces på struct-er, men det er ikke anbefalt ettersom å konvertere en struct til et interface vil føre til boxing.

 

public interface MyInterface
{
 void SomeFunction();
}

public class MyClass : MyInterface
{
 public void SomeFunction()
 {
   Console.WriteLine("Hello World!");
 }
}

public class MyExternalClass
{
 public MyInterface Interface { get; set; }
 public void DoSomething()
 {
   if(Interface != null)
     Interface.SomeFunction();
   else
     Console.WriteLine("No reference found.");
 }
}
public static class Main
{
 public static void Main()
 {
   MyClass a = new MyClass();
   var b = new ExternalClass()
   {
     Interface = a
   };
   b.DoSomething();
 }
}

Endret av GeirGrusom
Lenke til kommentar

Dette var rart. Sjekket akkurat hva jeg hadde i koden min og det var nesten d4et samme som du hadde foreslått:

 

public class AdvString : iAdvString
{
   private iAdvString _iExternal;
   public iAdvString iExternal
   {
       get{ return _iExternal;}
       set{ _iExternal = value;}
   }
}

Dette resulterer i "An object reference is required for the non-static field, method or property 'Advisor.CSharpInterOP._iExternal'

 

Men hvis jeg endrer til dette:

 

public class AdvString : iAdvString
{
   public iAdvString iExternal {get; set;}
}

Ja - da er alt ok?!?!?! Hva kommer det av tro?

Endret av HDSoftware
Lenke til kommentar

Nå blir vel autoproperties oversatt av compileren til nøyaktig samme kode som om du skulle skrevet med en privat member variabel som propertyen jobber med så vidt jeg vet. Uansett...det er ikke ulovlig å skrive som du har gjort. Denne koden her gjør jo akkurat det, og den fungerer fint.

public interface IFoo
   {
       string Bar();
       IFoo External { get; set; }
       string Name { get; set; }
   }

   public class Foo : IFoo
   {
       public string Name { get; set; }
       public string Bar()
       {
           return External.Name;
       }

       private IFoo external;
       public IFoo External
       {
           get
           {
               return external;
           }
           set
           {
               external = value;
           }
       }
   }

   class Program
   {
       static void Main(string[] args)
       {
           var a = new Foo() { Name = "Hi, I'm A" };
           var b = new Foo() { Name = "Hi, I'm B" };

           a.External = b;
           b.External = a;

           Console.WriteLine(a.Bar());
           Console.WriteLine(b.Bar());
           Console.ReadLine();
       }
   }

 

Vil skrive ut:

Hi, I'm B

Hi, I'm A

 

Sånn rent bortsett fra det, så ser jeg ikke helt poenget med konstruksjonen du prøver å oppnå her, men det er jo en annen sak :p

Lenke til kommentar

Konstruksjonen er å referere til interfacet og ikke objektet. I Clarion så er et Interface en egen referanse i et objekt og tanken er jo at jeg på den måten kan sende et interface til et objekt direkte. Jeg er bare usikker på hvordan det blir gjort i C#.

For din info:

Interface i Clarion iomplementeres slik:

 

MyClass Class(), implements(iMyInterface)

 

For å kalle interface metoder da så gjør jeg slik:

 

MyObject.iMyInterface.InterfaceMetode()

 

For å sende kunn interfacet til andre objekter så gjør jeg slik:

 

SomeOtherObject.TakeInterface(MyObject.iMyInterface)

 

 

i koden under TakeInterface så gjør jeg slik:

 

this.TakenInterface &= pReceivedInterface

 

Som du ser, selve interfacet i seg selv er en referanse. I C# så har jeg forstått det slik at et Interface bare er en slags kontrakt og at en metode som har et interface i prototypen automatisk vil kunen ta imot et hvilket som helst objekt som er utledet av interfacet. Det blir liksom litt annerledes en Clarion tankegangen, fordi det tyder jo på at adressen til objektet og interfacet er en og samme, men at .NET maskineriet fikser dette under huden på bakgrunn av prototype. Gjetter jo litt her, men det virker i hvertfall slik på meg...

Endret av HDSoftware
Lenke til kommentar

Du gjetter helt korrekt :)

 

public interface IFoo
   {
       string Name { get; set; }
   }

   public class A : IFoo
   {
       public string Name { get; set; }
   }

   public class B : IFoo
   {
       public string Name { get; set; }
   }

   public class C
   {
       public void WriteName(IFoo obj)
       {
           Console.WriteLine(obj.Name);
       }
   }


   class Program
   {
       static void Main(string[] args)
       {
           var a = new A() { Name = "Hi, I'm A" };
           var b = new B() { Name = "Hi, I'm B" };
           var c = new C();
           c.WriteName(a);
           c.WriteName(b);
           Console.ReadLine();
       }
   }

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...