Laden...

Interfaces mit statischem Übergabeparameter

Erstellt von Sakulrelda vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.095 Views
S
Sakulrelda Themenstarter:in
13 Beiträge seit 2014
vor 10 Jahren
Interfaces mit statischem Übergabeparameter

Hallo Community,

ich hätte da mal eine Frage bezüglich eines Interfaces.

Ich besitze das unten abgeblidete Interface! Zu diesem Interface gibt es natürlich verschiedene Klassen, welche das Interface implementieren. Manche Klassen benötigen also als Übergabeparameter ein File, andere welche das Interface aufrufen, jedoch nicht. Das Problem hierbei ist jedoch, dass folgender Fehler entsteht:

Fehlermeldung:
Statische typen können nicht als parameter verwendet werden

Desweiteren kann ich nicht auf das Interface verzichten, da später im Code
so etwas in der Art aufgerufen werden soll:

//Aufruf der Methode


public bool sendCommand(Cmd command)
        {
            try
            {
                send(command.execute());
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERR: SendCommand konnte nicht ausgeführt werden->" + ex.ToString());
                return false;
            }
        }


//Beispiel Klasse mit implementiertem Interface


 public class CmdProgramFlash : Cmd
    {

        public String SOH = "01";
        public String EOT = "04";
        public String DLE = "10";

        public String ProgramFlash = "03";

        /// <summary>
        /// Setzt das Frame zusammen und gibt dieses zurück
        /// </summary>
        /// <returns>Byte-Frame</returns>
        public byte[] execute()
        {
            int bufferLength = 0;
            byte[] buffer = new byte[1000];

            buffer[bufferLength++] = byte.Parse(ProgramFlash, System.Globalization.NumberStyles.HexNumber);

            unsafe
            {
                fixed (byte* pointer = &buffer[0])
                {
                    short value = ClcCrc(pointer, bufferLength);
                    buffer[bufferLength++] = (byte)value;
                    buffer[bufferLength++] = (byte)(value >> 8);
                }
            }

            int sendBufferLaenge = 0;
            byte[] sendBuffer = new byte[1040];

            //SOH Beginn des Frames
            sendBuffer[sendBufferLaenge++] = byte.Parse(SOH, System.Globalization.NumberStyles.HexNumber);

            byte b_eot = byte.Parse(EOT, System.Globalization.NumberStyles.HexNumber);
            byte b_soh = byte.Parse(SOH, System.Globalization.NumberStyles.HexNumber);
            byte b_dle = byte.Parse(DLE, System.Globalization.NumberStyles.HexNumber);

            for (int i = 0; i < bufferLength; i++)
            {
                if (buffer[i] == b_eot || buffer[i] == b_soh || buffer[i] == b_dle)
                {
                    sendBuffer[sendBufferLaenge++] = byte.Parse(DLE, System.Globalization.NumberStyles.HexNumber);
                }
                sendBuffer[sendBufferLaenge++] = buffer[i];
            }

            sendBuffer[sendBufferLaenge++] = byte.Parse(EOT, System.Globalization.NumberStyles.HexNumber);

            //Neue Erstellung eines Buffer, da ansonsten ein zu großer Buffer verschickt wird...
            byte[] realeBuffer = new byte[sendBufferLaenge];
            for (int i = 0; i < realeBuffer.Length; i++)
            {
                realeBuffer[i] = sendBuffer[i];
            }

            return realeBuffer;
        }

        /// <summary>
        /// CRC-Tabelle
        /// </summary>
        ushort[] crc_table = 
        { 
            0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef 
        };

        /// <summary>
        /// Berechnet einen Crc-Wert
        /// </summary>
        public unsafe short ClcCrc(byte* data, int len)
        {
            int i;
            short crc = 0;

            while (len > 0)
            {
                i = (crc >> 12) ^ (*data >> 4);
                crc = (short)(crc_table[i & 0x0F] ^ (crc << 4));
                i = (crc >> 12) ^ (*data >> 0);
                crc = (short)(crc_table[i & 0x0F] ^ (crc << 4));

                data++;
                len--;
            }

            ushort val = (ushort)(0xFFFF);
            short value = (short)(crc & val);
            return (short)(crc & val);
        }

//Interface-Klasse


public interface Cmd
    {
        byte[] execute(File f = null);
    }

Ich hoffe Ihr könnt mir helfen.

Mit freundlichen Grüßen - best regards

Lukas Adler

Fachinformatiker für Anwendungsentwicklung
staatl. gepr. WIA

S
417 Beiträge seit 2008
vor 10 Jahren

Hallo,

File ist nunmal eine statische Klasse, daher kannst du sie so nicht verwenden. Was geht wäre ein string als Dateiname oder FileInfo.

16.842 Beiträge seit 2008
vor 10 Jahren

Denke auch, dass die Fehlermeldung mehr als deutlich genug ist.

Sowas wäre auch denkbar:


    public interface IJob
    {
        void Execute( );
    }

    public class CopyJobPrefences
    {
        public System.IO.FileInfo File { get; set; }
    }

    public class CopyJob : IJob
    {
        private CopyJobPrefences _pref; 

        public CopyJob(CopyJobPrefences pref)
        {
           _pref = pref;
        }
        public void Execute( )
        {
            // Copy mit _pref
        }
    }

// Run
        public static void test( )
        {
            var pref = new CopyJobPrefences {File = /* File */};
            var copyJob = new CopyJob(pref);

           Consumer(job);
        }

        private static void Consumer( IJob job )
        {
            job.Execute();
        }


Edit: Snippet mit Sarc's Einwand editiert. Er hat natürlich Recht in diesem Fall.

S
417 Beiträge seit 2008
vor 10 Jahren

Ich denke von der Architektur her solltest du komplett auf den Parameter in der execute-Methode verzichten, denn du willst ja gerade nicht, dass sich der Aufrufer Gedanken darüber machen muss, ob er jetzt ein File übergeben muss oder nicht, denn dazu müsste er ja wieder wissen um welchen Command es sich handelt.
Abhängig von deiner bisherigen Architektur wäre es evtl. besser diesen Command-spezifischen Kontext über den Konstruktor des jeweiligen Commands bereitzustellen. Aber das ist natürlich abhängig davon wie du die Commands tatsächlich verwenden möchtest.

S
Sakulrelda Themenstarter:in
13 Beiträge seit 2014
vor 10 Jahren

Danke für die Hilfe. Problem ist gelöst und ich verstehe das ganze wieder ein stückchen besser

Mit freundlichen Grüßen - best regards

Lukas Adler

Fachinformatiker für Anwendungsentwicklung
staatl. gepr. WIA