[C#] Efficienter programmeren?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Ik ben begonnen met C# en het gaat prima na mijn idee. Ik snap veel, maar heb wel het idee dat ik inefficient aan het programmeren ben. Op internet zie je veel voorbeelden en met kopieren/plakken kom je een eind. Daarna probeer ik uiteraard de code te begrijpen.

Echter nu heb ik het idee dat ik het verkeerd aanpak. Voor elke byte die ik wil lezen open ik het bestand opnieuw met BinaryReader. Zat er eerst aan te denken om alle "bytes" in een array te zetten en deze dan uit te lezen, maar voor nu hoef ik nog niet te kijken naar performance gezien het snel werkt.

De code werkt en daar heb ik opzich geen vragen over, maar zou iemand mij kunnen vertellen of deze code efficienter geschreven kan worden? Of maakt het niet uit om elke keer een enkele byte te lezen met BinaryReader b.v.?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected string GetFileSize(string fileName)
        {
            FileInfo file = new FileInfo(fileName);
            long fileLength = file.Length;
            return fileLength.ToString();
        }

        protected string GetMD5HashFromFile(string fileName)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(fileName))
                {
                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
                }
            }
        }

        protected string GetSHA1HashFromFile(string fileName)
        {
            using (var md5 = SHA1.Create())
            {
                using (var stream = File.OpenRead(fileName))
                {
                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
                }
            }
        }

        protected string GetSHA256HashFromFile(string fileName)
        {
            using (var md5 = SHA256 .Create())
            {
                using (var stream = File.OpenRead(fileName))
                {
                    return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
                }
            }
        }

        public string GetSignatureFromFile(string fileName)
        {
            BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
            reader.BaseStream.Position = 0x0;
            byte[] data = reader.ReadBytes(0x2);
            reader.Close();

            string data_as_str = Encoding.Default.GetString(data);
            if(data_as_str != "MZ")
            {
                data_as_str = "Unknown";
            }
            return data_as_str;
        }

        protected string GetBytesInLastBlockFromFile(string fileName)
        {
            BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
            reader.BaseStream.Position = 0x2;
            byte[] data = reader.ReadBytes(0x2);        
            reader.Close();
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string GetBlocksFromFile(string fileName)
        {
            BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
            reader.BaseStream.Position = 0x4;
            byte[] data = reader.ReadBytes(0x2);
            reader.Close();
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string GetNumberOfRelocationEntriesFromFile(string fileName)
        {
            BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
            reader.BaseStream.Position = 0x6;
            byte[] data = reader.ReadBytes(0x2);
            reader.Close();
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string HeaderSizeInParagraphs(string fileName)
        {
            BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
            reader.BaseStream.Position = 0x8;
            byte[] data = reader.ReadBytes(0x2);
            reader.Close();
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "All Files|*.*";
            openFileDialog1.Title = "Select a File";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
                textBox2.Text = GetFileSize(openFileDialog1.FileName);
                textBox3.Text = GetMD5HashFromFile(openFileDialog1.FileName).ToLower();
                textBox4.Text = GetSHA1HashFromFile(openFileDialog1.FileName).ToLower();
                textBox5.Text = GetSHA256HashFromFile(openFileDialog1.FileName).ToLower();
                textBox6.Text = GetSignatureFromFile(openFileDialog1.FileName);
                textBox7.Text = GetBytesInLastBlockFromFile(openFileDialog1.FileName);
                textBox8.Text = GetBlocksFromFile(openFileDialog1.FileName);
                textBox9.Text = GetNumberOfRelocationEntriesFromFile(openFileDialog1.FileName);
                textBox10.Text = HeaderSizeInParagraphs(openFileDialog1.FileName);
            }
        }
    }
}

Acties:
  • 0 Henk 'm!

  • Dutchredgaming
  • Registratie: September 2014
  • Laatst online: 11-09 21:11

Dutchredgaming

ICT Beheerder

Schrijf je het zelf of gebruik je Visual Studio?

Review QNAP TS-230 NAS


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Dutchredgaming schreef op dinsdag 15 september 2015 @ 09:37:
Schrijf je het zelf of gebruik je Visual Studio?
Microsoft Visual Studio 2015 Professional :)

Acties:
  • 0 Henk 'm!

  • Cypher87
  • Registratie: Oktober 2004
  • Laatst online: 31-08 10:00
Je geeft zelf al aan wat je 'fout' doet (meerdere keren BinaryReader instantiëren voor hetzelfde bestand). Nu je het probleem weet is de stap naar de oplossing volgens mij vrij simpel.

Acties:
  • 0 Henk 'm!

  • boe2
  • Registratie: November 2002
  • Niet online

boe2

'-')/

Initialiseer je binaryreader in je button1_click method en geef die mee als argument in al die andere methods. Dan hoef je de file maar 1 keer te openen, steek hem meteen ook in een using block :)
Dutchredgaming schreef op dinsdag 15 september 2015 @ 09:37:
Schrijf je het zelf of gebruik je Visual Studio?
:?

[ Voor 6% gewijzigd door boe2 op 15-09-2015 10:14 ]

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.' - Pratchett.


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
boe2 schreef op dinsdag 15 september 2015 @ 10:13:
Initialiseer je binaryreader in je button1_click method en geef die mee als argument in al die andere methods. Dan hoef je de file maar 1 keer te openen, steek hem meteen ook in een using block :)


[...]

:?
Zoiets dus? Dit werkt inderdaad ook en is inderdaad mooier. Wat te doen met de methods? Ik gebruik veel methods om het voor mij zo overzichtelijk mogelijk te houden. Is het niet wat overdreven?

Ik heb het zo gedaan omdat ik op een bepaalde positie maar 1 of 2 bytes wilde uitlezen. Door gebruik te maken van 'reader.BaseStream.Position' in de methode leek het mij wel een redelijk oplossing.

Edit: Using block moest ik nog doen inderdaad. Goede tip :)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected string GetBytesInLastBlockFromFile(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x2;
            byte[] data = reader.ReadBytes(0x2);        
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }


        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "All Files|*.*";
            openFileDialog1.Title = "Select a File";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                BinaryReader reader = new BinaryReader(new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.None));
                textBox7.Text = GetBytesInLastBlockFromFile(reader);
                reader.Close();
            }
        }

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Squ1zZy schreef op dinsdag 15 september 2015 @ 10:24:
[...]


Zoiets dus? Dit werkt inderdaad ook en is inderdaad mooier. Wat te doen met de methods? Ik gebruik veel methods om het voor mij zo overzichtelijk mogelijk te houden. Is het niet wat overdreven?
Nee, absoluut niet. Kleine methoden met een enkele verantwoordelijkheid houden je code begrijpelijk en overzichtelijk. Zorg dan wel dat je methodenamen ook duidelijk zijn. Op die manier is je code ook prettig terug te lezen (button1_Click en TextBox1 tm/ 7 zijn juist weer heel foute namen)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Janoz schreef op dinsdag 15 september 2015 @ 10:28:
[...]

Nee, absoluut niet. Kleine methoden met een enkele verantwoordelijkheid houden je code begrijpelijk en overzichtelijk. Zorg dan wel dat je methodenamen ook duidelijk zijn. Op die manier is je code ook prettig terug te lezen (button1_Click en TextBox1 tm/ 7 zijn juist weer heel foute namen)
Dit is een fout die ik met scripten ook veel maak. Je begint klein en gebruik de standaard namen of met scripten b.v. $bla, $lol, $test etc. Na een tijd wordt het iets langer en kan je alles weer gaan ombouwen :P

Moet nog aanleren om gelijk al beginnen met labels, buttons etc aan te passen van naam.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Squ1zZy schreef op dinsdag 15 september 2015 @ 09:33:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
protected string GetMD5HashFromFile(string fileName)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(fileName))
        {
            return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
        }
    }
}

protected string GetSHA1HashFromFile(string fileName)
{
    using (var md5 = SHA1.Create())
    {
        using (var stream = File.OpenRead(fileName))
        {
            return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
        }
    }
}

protected string GetSHA256HashFromFile(string fileName)
{
    using (var md5 = SHA256 .Create())
    {
        using (var stream = File.OpenRead(fileName))
        {
            return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", string.Empty);
        }
    }
}
Dat heel spul kun je al refactoren naar:
C#:
1
2
3
4
5
6
7
8
9
10
11
protected string GetHashFromStream(HashAlgorithm hashAlgo, Stream stream)
{
    return string.Concat(hashAlgo.ComputeHash(stream).Select(x => x.ToString("X2")));
}

protected string GetHashFromFile(string hashAlgorithm, string fileName)
{
    using (var stream = File.OpenRead(fileName))
    using (var hashalgo = HashAlgorithm.Create(hashAlgorithm))
        return GetHashFromStream(hashalgo, stream);
}

Waarbij je dan wel de hash als string specificeert ("MD5"); wil je dat niet dan geef je gewoon de MD5.Create() result (of SHA1.Create() result of...) mee aan GetHashFromStream() (vergeet je using of dispose dan niet!).

[ Voor 12% gewijzigd door RobIII op 15-09-2015 10:44 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Squ1zZy schreef op dinsdag 15 september 2015 @ 10:34:
[...]


Dit is een fout die ik met scripten ook veel maak. Je begint klein en gebruik de standaard namen of met scripten b.v. $bla, $lol, $test etc. Na een tijd wordt het iets langer en kan je alles weer gaan ombouwen :P

Moet nog aanleren om gelijk al beginnen met labels, buttons etc aan te passen van naam.
Ik begin nooit met dergelijke variabelen, ook niet als iets klein is. Daarnaast probeer ik de scope van variabelen zo klein mogelijk te houden. Dat zorgt er voor dat het later hernoemen van een variabele ook helemaal geen probleem hoeft te zijn. Alle voorkomens staan immers vlak bij elkaar.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Normaal gesproken zijn veel methodes prima maar in dit geval zijn veel van die methodes eigenlijk maar 1 regel zo ongeveer als je het op de juiste volgorde zet. Als in zoiets:

C#:
1
2
3
signatureTextBox.Text = reader.ReadBytes(2).ToHex(); // pos 0x0
bytesInLastBlockFromFileTextBox.Text = reader.ReadBytes(2).ToHex(); // pos 0x2
...


(met ToHex uit http://stackoverflow.com/a/3974535)

In de huidige code zou ik ook overal dit stukje overal hebben gerefactord naar 1 methode, Visual Studio kan ze allemaal in 1x vervangen:
C#:
1
2
3
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;

Maar ik vind .ToHex mooier ipv BytesToHex(..), dat is persoonlijke voorkeur.

Overigens is het een eenmalig iets per useractie, dus zal de performance van de originele code prima zijn geweest.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
offtopic:
HOLY... :X Die verdient de prijs voor 's werelds lelijkste "ToHex" implementatie ever :X
Het zal best "snel" zijn zoals beweerd wordt, maar dat is hier totaal verwaarloosbaar als je over een array van hooguit een paar tiental bytes itereert (de byte[] die de hash returned) en tenzij je miljoenen hashes gaat berekenen (waarom zou je ze dan uberhaupt in string representatie willen hebben en niet gewoon als byte[] bewaren) zie ik hier echt het nut niet van.

[ Voor 42% gewijzigd door RobIII op 15-09-2015 11:02 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
RobIII schreef op dinsdag 15 september 2015 @ 10:58:
[...]

HOLY... :X Die verdient de prijs voor 's werelds lelijkste "ToHex" implementatie ever :X
Hij is met afstand het snelst van de methodes daar, en zag zo snel geen andere extentie. Linkje erbij en niet meer naar kijken ;)

Edit: snelheid is inderdaad geen argument, maar je moet niet library methodes die goed werken intern gaan bekijken..

[ Voor 13% gewijzigd door pedorus op 15-09-2015 11:03 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Komt dit met ervaring? Of moet ik stoppen met programmeren? :P

Code werkte prima, maar echt netjes was het niet. Ik wist zoiets wel, maar om dan te googlen om het "netter" te schrijven is lastiger.

Heb het nu zo geschreven:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public string GetFileSize(string fileName)
        {
            FileInfo file = new FileInfo(fileName);
            long fileLength = file.Length;
            return fileLength.ToString();
        }

        public string GetSignatureFromFile(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x0;
            byte[] data = reader.ReadBytes(0x2);
            string data_as_str = Encoding.Default.GetString(data);
            if(data_as_str != "MZ")
            {
                data_as_str = "Unknown";
            }
            return data_as_str;
        }

        public static class Algorithms
        {
            public static readonly HashAlgorithm MD5 = new MD5CryptoServiceProvider();
            public static readonly HashAlgorithm SHA1 = new SHA1Managed();
            public static readonly HashAlgorithm SHA256 = new SHA256Managed();
            //public static readonly HashAlgorithm SHA512 = new SHA512Managed();
        }

        public static string GetHashFromFile(string fileName, HashAlgorithm algorithm)
        {
            using (var stream = new BufferedStream(File.OpenRead(fileName), 100000))
            {
                return BitConverter.ToString(algorithm.ComputeHash(stream)).Replace("-", string.Empty);
            }
        }

        protected string GetBytesInLastBlockFromFile(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x2;
            byte[] data = reader.ReadBytes(0x2);        
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string GetBlocksFromFile(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x4;
            byte[] data = reader.ReadBytes(0x2);
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string GetNumberOfRelocationEntriesFromFile(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x6;
            byte[] data = reader.ReadBytes(0x2);
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        protected string HeaderSizeInParagraphs(BinaryReader reader)
        {
            reader.BaseStream.Position = 0x8;
            byte[] data = reader.ReadBytes(0x2);
            string data_as_hex = BitConverter.ToString(data);
            data_as_hex = data_as_hex.Replace("-", string.Empty);
            return data_as_hex;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Filter = "All Files|*.*";
            openFileDialog1.Title = "Select a File";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
                textBox2.Text = GetFileSize(openFileDialog1.FileName);
                string checksumMd5 = GetHashFromFile(openFileDialog1.FileName, Algorithms.MD5);
                string checksumSHA1 = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA1);
                string checksumSHA256 = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA256);
                textBox3.Text = checksumMd5;
                textBox4.Text = checksumSHA1;
                textBox5.Text = checksumSHA256;

                using (BinaryReader reader = new BinaryReader(new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.None)))
                {
                    textBox6.Text = GetSignatureFromFile(reader);
                    textBox7.Text = GetBytesInLastBlockFromFile(reader);
                    textBox8.Text = GetBlocksFromFile(reader);
                    textBox9.Text = GetNumberOfRelocationEntriesFromFile(reader);
                    textBox10.Text = HeaderSizeInParagraphs(reader);
                    reader.Close();
                }
            }
        }
    }
}


@pedrorus: Intressant stukje. Zo ook even lezen :)

Bedankt allen.. Moet nog veel leren merk ik.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
pedorus schreef op dinsdag 15 september 2015 @ 11:02:
Edit: snelheid is inderdaad geen argument, maar je moet niet library methodes die goed werken intern gaan bekijken..
Totdat er subtiele bugs in blijken te zitten ;)
Daarbij ben ik niet kapot van een extensionmethod op string; zo kan ik nu "FooBarBaz".HexToBytes() doen... :X

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • +1 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 17-09 10:39

Cloud

FP ProMod

Ex-moderatie mobster

Je blijft altijd leren en dit soort dingen worden absoluut met ervaring beter. Stap 1 heb je al voltooid, inzien dat het beter kan ;) Zolang je kritisch blijft naar je eigen code, kom je verder.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

RobIII schreef op dinsdag 15 september 2015 @ 10:58:
[...]

offtopic:
HOLY... :X Die verdient de prijs voor 's werelds lelijkste "ToHex" implementatie ever :X
Waarom :? De code is clean en overzichtelijk. Kijk, je kunt argueen dat hij niet die constanten moet gebruiken. In C++ typ ik meestal "0123456789abcdef"[index] om het juiste hex character te krijgen (of als je echt hip bent: index["0123456789abcdef"] >:) tentamenvraag: waarom werkt dit ook?). Maar anders dan dat is hij prima.

[ Voor 10% gewijzigd door .oisyn op 15-09-2015 11:13 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Squ1zZy schreef op dinsdag 15 september 2015 @ 11:06:
Komt dit met ervaring? Of moet ik stoppen met programmeren? :P
Een goede programmeur is lui; maar lui zijn kun je leren ;)
Squ1zZy schreef op dinsdag 15 september 2015 @ 11:06:

code:
1
2
3
4
5
6
string checksumMd5 = GetHashFromFile(openFileDialog1.FileName, Algorithms.MD5);
string checksumSHA1 = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA1);
string checksumSHA256 = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA256);
textBox3.Text = checksumMd5;
textBox4.Text = checksumSHA1;
textBox5.Text = checksumSHA256;
Waarom die extra variabelen die je daarna toch niet meer gebruikt? Los van de "textBox3" etc. naming:
C#:
1
2
3
textBox3.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.MD5);
textBox4.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA1);
textBox5.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA256);

[ Voor 9% gewijzigd door RobIII op 15-09-2015 11:13 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
RobIII schreef op dinsdag 15 september 2015 @ 11:12:
[...]

Een goede programmeur is lui; maar lui zijn kun je leren ;)


[...]


Waarom die extra variabelen die je daarna toch niet meer gebruikt? Los van de "textBox3" etc. naming:
C#:
1
2
3
textBox3.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.MD5);
textBox4.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA1);
textBox5.Text = GetHashFromFile(openFileDialog1.FileName, Algorithms.SHA256);
Die had ik net aangepast inderdaad. Gaat allemaal niet zo snel op mijn leeftijd en als beginnende "prutser" :P

Ben aan het kijken wat je precies bedoelt met "voor 's werelds lelijkste "ToHex" implementatie ever", maar dat kost me even wat tijd ben ik bang. Moet nog even googlen daarvoor :)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Omdat 't stikt van de magic consts, omdat er niet in 1 oogopslag duidelijk is wat er gebeurt, het gebruik van de ternary maakt dat nog erger. Ja, het is prima "clean" code en vast heel snel en vanuit "hack0rz perspectief" ook heel 'mooi'. Maar voor doorsnee, run-of-the-mill, code vind ik dit niet bepaald een pareltje als er zat betere/leesbaardere alternatieven zijn. Tenzij performance een issue is en je profiler deze code als hotspot markeert zou ik gewoon gaan voor een van de andere alternatieven die daar genoemd worden en vele malen leesbaarder zijn. En laten we wel wezen, voor jou en je achtergrond (en vele anderen net zo overigens, je bent daarin niet uniek ;) ) is dit, inderdaad, prima leesbare code; maar er zijn ook devvers die hier een dag of langer naar kunnen staren zonder te snappen wat er gebeurt ;)

[ Voor 31% gewijzigd door RobIII op 15-09-2015 11:20 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
RobIII schreef op dinsdag 15 september 2015 @ 11:07:
[...]

Totdat er subtiele bugs in blijken te zitten ;)
Misschien heeft BitConverter ze intern ook wel ;) Maar het lijkt me onwaarschijnlijk.
Daarbij ben ik niet kapot van een extensionmethod op string; zo kan ik nu "FooBarBaz".HexToBytes() doen... :X
Die zou ik niet overnemen, maar .ToHex op een byte array lijkt me prima. Best handige functie.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

RobIII schreef op dinsdag 15 september 2015 @ 11:16:
[...]

Omdat 't stikt van de magic consts
Dat is een punt waarmee ik het inderdaad eens ben.
omdat er niet in 1 oogopslag duidelijk is wat er gebeurt
Tja, dat ligt aan jou denk ik dan. Het is gewoon redelijk obvious: loop over alle bytes, en doe iets met resp. de onderste en bovenste 4 bits van de byte. En stop het geconverteerde deel in een char array.
het gebruik van de ternary maakt dat nog erger
Oneens.
en vanuit "hack0rz perspectief" ook heel 'mooi'
Bitch please :z

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

RobIII schreef op dinsdag 15 september 2015 @ 10:58:
[...]

offtopic:
HOLY... :X Die verdient de prijs voor 's werelds lelijkste "ToHex" implementatie ever :X
Het zal best "snel" zijn zoals beweerd wordt, maar dat is hier totaal verwaarloosbaar als je over een array van hooguit een paar tiental bytes itereert (de byte[] die de hash returned) en tenzij je miljoenen hashes gaat berekenen (waarom zou je ze dan uberhaupt in string representatie willen hebben en niet gewoon als byte[] bewaren) zie ik hier echt het nut niet van.
MWah, ik ben met pedorus en .oisyn. Vol verwachting opende ik het stackoverflow linkje, maar eigenlijk viel het mij alles mee. Daarnaast is dit natuurlijk code waarvan de werking uitstekend met een unittest te valideren is.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
.oisyn schreef op dinsdag 15 september 2015 @ 11:19:
Tja, dat ligt aan jou denk ik dan. Het is gewoon redelijk obvious: loop over alle bytes, en doe iets met resp. de onderste en bovenste 4 bits van de byte. En stop het geconverteerde deel in een char array.
Jij ziet 't, ik zie 't, maar je maakt me niet wijs dat jij oprecht gelooft dat 't merendeel van onze beroepspopulatie dit zonder problemen leest. Als de functie niet "ToHex()" had geheten hadden velen niet snel doorgehad wat hier gebeurde. Of jij hebt een hogere dunk van de doorsnee devver dan ik, dat kan ook :+
:D een smiley had daar misschien niet misstaan :P

[ Voor 8% gewijzigd door RobIII op 15-09-2015 11:34 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

RobIII schreef op dinsdag 15 september 2015 @ 11:22:
[...]

Jij ziet 't, ik zie 't, maar je maakt me niet wijs dat jij oprecht gelooft dat 't merendeel van onze beroepspopulatie dit zonder problemen leest. Als de functie niet "ToHex()" had geheten hadden velen niet snel doorgehad wat hier gebeurde. Of jij hebt een hogere dunk van de doorsnee devver dan ik, dat kan ook :+
Dat is irrelevant. Als je niet snapt hoe je bits moet manipuleren om een byte naar 2 hex chars te converteren, heb je in eerste plaats al niets te zoeken in die functie.
RobIII schreef op dinsdag 15 september 2015 @ 11:22:
:D een smiley had daar misschien niet misstaan :P
Hoofdletter Z getikt ipv een kleine z 8)7 die oogt toch wat vriendelijker ;)

[ Voor 16% gewijzigd door .oisyn op 15-09-2015 11:44 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Squ1zZy schreef op dinsdag 15 september 2015 @ 10:24:
Zoiets dus? Dit werkt inderdaad ook en is inderdaad mooier. Wat te doen met de methods? Ik gebruik veel methods om het voor mij zo overzichtelijk mogelijk te houden. Is het niet wat overdreven?
Zeker niet!

Lees: SOLID

Het Single Responsibility Principle is misschien wel het belangrijkste princiepe van de 5 basisprinciepes. Het grootste probleem van code is dat de complexiteit snel voorbij het punt stijgt waarbij een enkele persoon, hoe ervaren ook, een compleet mentaal model in zijn hoofd kan houden. Door gewoon nette methodes (en classes) te maken die gewoon 1 ding heel goed doen, hoef je een stuk minder in je hoofd te houden.
RobIII schreef op dinsdag 15 september 2015 @ 11:16:
Omdat 't stikt van de magic consts, omdat er niet in 1 oogopslag duidelijk is wat er gebeurt[/small]
De functie heet "ToHex", je alloceert een char array 2x de size van de input en je doet een for-loop. Ra ra wat zou er gebeuren? Ik ben het er niet mee eens dat het onduidelijk is. Wat de functie doet is meteen duidelijk. Hoe hij het doet is duidelijk in de code.

[ Voor 22% gewijzigd door Hydra op 15-09-2015 11:51 ]

https://niels.nu


Acties:
  • +1 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 20:53

Haan

dotnetter

Hydra schreef op dinsdag 15 september 2015 @ 11:45:
[...]


Zeker niet!

Lees: SOLID

Het Single Responsibility Principle is misschien wel het belangrijkste princiepe van de 5 basisprinciepes. Het grootste probleem van code is dat de complexiteit snel voorbij het punt stijgt waarbij een enkele persoon, hoe ervaren ook, een compleet mentaal model in zijn hoofd kan houden. Door gewoon nette methodes (en classes) te maken die gewoon 1 ding heel goed doen, hoef je een stuk minder in je hoofd te houden.
Goed punt inderdaad. De meeste code van de TS hoort niet in de code behind van het form thuis, maar in een 'FileHelper'-achtige class (ik ben nooit zo creatief met namen ;) )
Daarbij kan je de GetXXX methods ook door properties vervangen.

Dus bijvoorbeeld
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class FileHelper
{
    private readonly FileInfo file;

    public string FileName { get; private set; }

    public long FileSize 
    {
        get 
        {
             return file.Length;
        }
    }

// etc. 

    public FileHelper(string fileName)
    {
        FileName = fileName;
        fileInfo = new FileInfo(fileName);
    }

}

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Kwam via FP op dit topic binnengewaaid, en voor mij blijft het bij C++, maar ik neem aan dat ook C# Visual Studio ASCII constantes accepteert?

Dan is het simpelweg:
code:
1
c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);


Naar
code:
1
c[cx] = (char)(b > 9 ? b - 10 + 'a' : b + '0');


Exact dezelfde code nadat het gecompileerd is, maar wel leesbaarder. (Vind ik iig).

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sissors schreef op dinsdag 15 september 2015 @ 13:14:
Kwam via FP op dit topic binnengewaaid, en voor mij blijft het bij C++, maar ik neem aan dat ook C# Visual Studio ASCII unicode constantes accepteert?
;)

[ Voor 18% gewijzigd door .oisyn op 15-09-2015 14:40 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Wat is eigenlijk de rationele achter de b + 0x37 + 0x20? Waarom niet gewoon b + 0X57?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarschijnlijk omdat die 0x20 het verschil maakt tussen hoofletter en kleine letter. Maar als je dan toch al zo verbose bent, doe dan ook gewoon b - 10 + 0x41 + 0x20, ipv die +0x41 en -10 wel te combineren, maar de +0x20 niet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 00:08
Gebruik ook tools als http://vsrefactoringessentials.com/ of resharper. Die geven je tips bij code die wat anders kan (niet altijd beter wbt readability etc.)

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • DonJunior
  • Registratie: Februari 2008
  • Laatst online: 21:59
..en dan nu nog alles asynchroon. Anders hangt je applicatie bij elke IO operatie en dat wil je niet.

*sowieso


Acties:
  • 0 Henk 'm!

  • Xudonax
  • Registratie: November 2010
  • Laatst online: 19:46
Je kunt ook nog dit stukje code wat mooier maken :)

code:
1
2
3
4
5
6
7
8
protected string GetNumberOfRelocationEntriesFromFile(BinaryReader reader)
{
    reader.BaseStream.Position = 0x6;
    byte[] data = reader.ReadBytes(0x2);
    string data_as_hex = BitConverter.ToString(data);
    data_as_hex = data_as_hex.Replace("-", string.Empty);
    return data_as_hex;
}


Je doet nu overal vrijwel hetzelfde, je kunt dat stuk ook weer lostrekken in een aparte functie:

code:
1
2
3
4
5
6
7
private string GetByteFromReader(BinaryReader reader, int position) {
    reader.BaseStream.Position = position;
    byte[] data = reader.ReadBytes(0x2);
    string data_as_hex = BitConverter.ToString(data);
    data_as_hex = data_as_hex.Replace("-", string.Empty);
    return data_as_hex;
}


En dan vervolgens al je functies aanpassen zodat ze GetByteFromReader aanroepen met de juiste positie. Eventueel kun je van de 0x2 ook nog een parameter maken. Het voordeel is dat als je dingen gaat aanpassen, het maar op één plaats hoeft.

Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Xudonax schreef op dinsdag 15 september 2015 @ 15:03:
Je kunt ook nog dit stukje code wat mooier maken :)

code:
1
2
3
4
5
6
7
8
protected string GetNumberOfRelocationEntriesFromFile(BinaryReader reader)
{
    reader.BaseStream.Position = 0x6;
    byte[] data = reader.ReadBytes(0x2);
    string data_as_hex = BitConverter.ToString(data);
    data_as_hex = data_as_hex.Replace("-", string.Empty);
    return data_as_hex;
}


Je doet nu overal vrijwel hetzelfde, je kunt dat stuk ook weer lostrekken in een aparte functie:

code:
1
2
3
4
5
6
7
private string GetByteFromReader(BinaryReader reader, int position) {
    reader.BaseStream.Position = position;
    byte[] data = reader.ReadBytes(0x2);
    string data_as_hex = BitConverter.ToString(data);
    data_as_hex = data_as_hex.Replace("-", string.Empty);
    return data_as_hex;
}


En dan vervolgens al je functies aanpassen zodat ze GetByteFromReader aanroepen met de juiste positie. Eventueel kun je van de 0x2 ook nog een parameter maken. Het voordeel is dat als je dingen gaat aanpassen, het maar op één plaats hoeft.
Ook een goeie inderdaad. Bedankt voor alle tips :)

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
DonJunior schreef op dinsdag 15 september 2015 @ 14:58:
..en dan nu nog alles asynchroon. Anders hangt je applicatie bij elke IO operatie en dat wil je niet.
Really?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:29
Zolang je het op dezelfde thread als de UI blijft doen wel ja. Dit soort zaken wil je op een andere thread uitvoeren. Eigenlijk wil je alle dingen op een andere thread uitvoeren, maar een nieuwe thread starten kan negatiever uitpakken en om nu een task library met thread pool te gaan lopen schrijven of erbij te halen is vaak ook wat overkill.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Caelorum schreef op dinsdag 15 september 2015 @ 17:46:
Dit soort zaken wil je op een andere thread uitvoeren.
Die beslissing laat je aan de caller over imho.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:29
farlane schreef op dinsdag 15 september 2015 @ 17:58:
[...] Die beslissing laat je aan de caller over imho.
Ja, dat is leuk in een library die door anderen wordt gebruikt, maar we gaan hier wat offtopic. Mijn punten en die van DonJunior staan nog steeds: momenteel blockt het de UI thread.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Caelorum schreef op dinsdag 15 september 2015 @ 17:46:
[...]

Zolang je het op dezelfde thread als de UI blijft doen wel ja. Dit soort zaken wil je op een andere thread uitvoeren. Eigenlijk wil je alle dingen op een andere thread uitvoeren, maar een nieuwe thread starten kan negatiever uitpakken en om nu een task library met thread pool te gaan lopen schrijven of erbij te halen is vaak ook wat overkill.
Task.Run en TaskFactory.StartNew maken dat i.c.m. async/await een stuk makkelijker. Gewoon in het .NET framework en de C# taal inbegrepen. Niks geen third-party libraries of eigen geschreven vierkante wielen nodig.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Haan schreef op dinsdag 15 september 2015 @ 12:36:

De meeste code van de TS hoort niet in de code behind van het form thuis, maar in een 'FileHelper'-achtige class (ik ben nooit zo creatief met namen ;) )
Daarbij kan je de GetXXX methods ook door properties vervangen.
Kans is nagenoeg 100% dat je, wanneer je één v/d waardes uit de headers nodig hebt, de andere waardes ook nodig gaat hebben. Nog beter doe je dus iets als het volgende en encapsuleer je het verwerken van de file header data gewoon ineens. Pakt ook gelijk het bool TryOperation(TIn input, out TOut value) patroon mee om iets beter met exceptions om te kunnen gaan.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class HeaderData
{
  private HeaderData() { }
  
  public string LastBlock           { get; private set; }
  public string Blocks              { get; private set; }
  public string RelocationEntries   { get; private set; }
  public string ParagraphHeaderSize { get; private set; }

  private string BytesToHex(byte[] buffer, int length, int offset)
  {
    return BitConverter
      .ToString(buffer, offset, length)
      .Replace("-", "");
  }
  
  public static bool TryLoadFrom(string fileName, out HeaderData result, bool throwOnError)
  {
    if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName");
    
    if (!File.Exists(fileName))
    {
      result = null;
      if (throwOnError) throw new FileNotFoundException("Not Found", fileName);
      return false;
    }

    try
    {
      byte[] buffer;

      using (var reader = new BinaryReader(File.Open(
        fileName,
        FileMode.Open,
        FileAccess.Read,
        FileShare.None
      )))
      {
        buffer = reader.ReadBytes(10);
        reader.Close();
      }

      result = new HeaderData
      {
        LastBlock           = BytesToHex(buffer, 2, 2),
        Blocks              = BytesToHex(buffer, 2, 4),
        RelocationEntries   = BytesToHex(buffer, 2, 6),
        ParagraphHeaderSize = BytesToHex(buffer, 2, 8)
      };

      return true;
    }
    catch
    {
      result = null;

      if (throwOnError) throw;
      return false;
    }
  }
}


Squ1zZy; lees het eens door en probeer het te begrijpen. Het is niet zo moeilijk qua code of algoritmiek. Het is in het begin alleen wat moelijk om bij je initiële aanzet meteen de juiste opzet te kiezen. Maar als je een klein beetje een knobbel hebt voor programmeerwerk, zul je zien dat je daar gaandeweg gevoel voor gaat ontwikkelen.

Paar zaken die ik er even voor je uitlicht:
  • Het TryOperation patroon is iets wat bekend is bij andere C# developers vanuit classes in het .NET framework. Het is herkenbaar en meteen duidelijk en helpt met error afhandeling. (Je wilt niet altijd dat consumers van jouw code zelf exceptions moeten gaan afhandelen.)
  • Daarnaast de exception handling zelf. Let even op dat alles wat je met IDisposables doet en wat mogelijk een exception kan geven (dus zeker alles met readers en streams) netjes in een try/catch/finally of using block zit. In het geval van bovenstaande allebei, omdat we als er een exception optreedt mogelijk een boolean false terug willen geven.
  • Let ook even op hoe je een exception rethrowt. Doe het altijd zo, want anders vernietig je de stacktrace. (Behalve natuurlijk als het juist het doel was om de stacktrace te vernietigen, bijv. omdat je geen details uit security-gevoelige code wilt lekken.)
  • En let even op de andere overloads en de shorthand methods. Het .NET framework zit er vol mee en ze kunnen heel erg helpen om je code duidelijk leesbaar te houden.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
R4gnax schreef op dinsdag 15 september 2015 @ 21:18:
• Het TryOperation patroon is iets wat bekend is bij andere C# developers vanuit classes in het .NET framework. Het is herkenbaar en meteen duidelijk en helpt met error afhandeling. (Je wilt niet altijd dat consumers van jouw code zelf exceptions moeten gaan afhandelen.)
Echt waar? Het zorgt er volgens mij voor dat je juist iets met een exception moet gaan doen, want je krijgt een boolean terug ipv het resultaat waarnaar je op zoek bent. Ik zou het een anti-pattern noemen.
Vergelijk:
C#:
1
2
var res = RoepFunctieAan()
//doe iets

En evt heel ergens ander error handling.
Met:
C#:
1
2
3
4
5
6
ResultaatType res;
if (TryRoepFunctieAan(res)) {
  //doe iets
} else {
  //functie faalt, en nu? Wat was er mis? Getlasterror?
}


(Scala heeft bijvoorbeeld een Try(...) functie waarbij je van een normale functie alsnog een try-functie kan maken. Dat lijkt me handiger in die gevallen dat dit wel nuttig is.)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 00:25

The Eagle

I wear my sunglasses at night

RobIII schreef op dinsdag 15 september 2015 @ 10:58:
[...]

offtopic:
HOLY... :X Die verdient de prijs voor 's werelds lelijkste "ToHex" implementatie ever :X
Het zal best "snel" zijn zoals beweerd wordt, maar dat is hier totaal verwaarloosbaar als je over een array van hooguit een paar tiental bytes itereert (de byte[] die de hash returned) en tenzij je miljoenen hashes gaat berekenen (waarom zou je ze dan uberhaupt in string representatie willen hebben en niet gewoon als byte[] bewaren) zie ik hier echt het nut niet van.
Vermoedelijk iets met monitoren, analyseren en voorspellen van bijv. hele grote netwerken dmv Big Data technieken. Kan me dr best wat bij voorstellen aangezien ik per 1 oktober in een nieuwe baan ga beginnen die o.m. Dat soort dingen behelst :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • 0 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 00:29
pedorus schreef op dinsdag 15 september 2015 @ 21:55:
[...] Echt waar? Het zorgt er volgens mij voor dat je juist iets met een exception moet gaan doen, want je krijgt een boolean terug ipv het resultaat waarnaar je op zoek bent. Ik zou het een anti-pattern noemen.[...]
De Try** functies zijn er dan ook voor als je verwacht dat wat je gaat doen een kans heeft te falen. Excepties zijn voor exceptionele gebeurtenissen. Zooi die je dus in principe niet verwacht dat gaat gebeuren (maar mocht het toch gebeuren, moet je het wel fatsoenlijk afhandelen).
Het is dus niet een anti-pattern, maar wel 1 die je in de juiste gevallen moet inzetten.

[ Voor 42% gewijzigd door Caelorum op 15-09-2015 22:01 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Caelorum schreef op dinsdag 15 september 2015 @ 22:00:
[...]

De Try** functies zijn er dan ook voor als je verwacht dat wat je gaat doen een kans heeft te falen. Excepties zijn voor exceptionele gebeurtenissen. Zooi die je dus in principe niet verwacht dat gaat gebeuren (maar mocht het toch gebeuren, moet je het wel fatsoenlijk afhandelen).
Het is dus niet een anti-pattern, maar wel 1 die je in de juiste gevallen moet inzetten.
Dat, en in het geval waar je wel een exception wilt verwerken is er de boolean throwOnError parameter die alsnog exceptions laat propageren. ;)

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ik verwijs graag door naar deze blog: http://weblogs.asp.net/alex_papadimoulis/396734 TL;DR: gebruik Exceptions en ga niet moeilijk doen met andere dingen om het naar boven te bubbelen.

De reden voor de TryParse functies is trouwens dat die sneller zijn al wil je veel testen en die werken intern niet met try/catch, maar dat is een vrij bijzonder geval. Het is daadwerkelijk een use-case om te bepalen of iets echt een double is en niet iets anders. Hier verwacht je geen exception, doe je wel try/catch, en schelen die nanoseconden niets.
R4gnax schreef op dinsdag 15 september 2015 @ 22:03:
Dat, en in het geval waar je wel een exception wilt verwerken is er de boolean throwOnError parameter die alsnog exceptions laat propageren. ;)
Allemaal extra code en parameters, die je dan ook in elke soortgelijke functie nodig hebt. :p
The Eagle schreef op dinsdag 15 september 2015 @ 22:00:
[...]

Vermoedelijk iets met monitoren, analyseren en voorspellen van bijv. hele grote netwerken dmv Big Data technieken. Kan me dr best wat bij voorstellen aangezien ik per 1 oktober in een nieuwe baan ga beginnen die o.m. Dat soort dingen behelst :)
Zeker met Big Data zou ik zeggen dat als er dingen in hex strings worden opgeslagen dat er iets hopeloos mis is gegaan... Hex is eigenlijk alleen voor mensen bedoelt om naar te kijken, en schermen hebben een maximale grootte.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • DonJunior
  • Registratie: Februari 2008
  • Laatst online: 21:59
farlane schreef op dinsdag 15 september 2015 @ 17:58:
[...]

Die beslissing laat je aan de caller over imho.
Je kan het natuurlijk ook proberen te onderbouwen dat maakt het voor mij ook een stuk duidelijker wat je nu wilt zeggen. Misschien kan ik er dan ook nog wat van leren. In plaats van zulke nietszeggende opmerkingen te plaatsen waar echt niemand wat mee kan.
Het is niet erg hoor mensen als je iets van een ander kan leren. Ik sta daarom altijd open voor input van een ander.

*sowieso


Acties:
  • +1 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Als hier al een discussie ontstaat. Hoe kan een prutser zoals ik dit dan in 1x goed doen? :D

Bedankt allen voor de reacties. Alles werkt en heb veel geleerd...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
DonJunior schreef op woensdag 16 september 2015 @ 07:04:
Je kan het natuurlijk ook proberen te onderbouwen dat maakt het voor mij ook een stuk duidelijker wat je nu wilt zeggen.
Dingen rücksichtslos uitbreiden met asynchrone concepten is wat mij betreft onnodige complexiteit introduceren. Het zou best aan de hand kunnen zijn, maar dan zou je nog de constructie wat anders moeten maken om de gebruiker de keuze te laten maken of het synchroon dan wel asynchroon zou moeten gebeuren.
Bijvoorbeeld door wat al gesuggereerd wordt de methoden die iets doen over te brengen naar een andere class en op de plekken waar je deze gebruikt te bepalen of het nodig is om het asynchroon te doen of niet.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is sowieso een wassen neus als je interface verder niet toestaat om acties te ondernemen terwijl het proces bezig is. En dat is conceptueel veel moeilijker toe te voegen dan wat async calls hier en daar.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • DonJunior
  • Registratie: Februari 2008
  • Laatst online: 21:59
farlane schreef op woensdag 16 september 2015 @ 10:09:
[...]

Dingen rücksichtslos uitbreiden met asynchrone concepten is wat mij betreft onnodige complexiteit introduceren. Het zou best aan de hand kunnen zijn, maar dan zou je nog de constructie wat anders moeten maken om de gebruiker de keuze te laten maken of het synchroon dan wel asynchroon zou moeten gebeuren.
Bijvoorbeeld door wat al gesuggereerd wordt de methoden die iets doen over te brengen naar een andere class en op de plekken waar je deze gebruikt te bepalen of het nodig is om het asynchroon te doen of niet.
Dat ben ik met je eens. Zie? Zo komt het ook voor mij wat logischer over dan alleen je opmerking 'Really'
Ik heb namelijk altijd geleerd dat je IO operaties eigenlijk altijd asynchroon moet doen zodat (bij een wat langere response tijd) de interface niet blijft hangen. Dat was dan ook de enige opmerking die ik maakte. Hoe dit toe te passen is aan de TS zelf natuurlijk. :)

*sowieso


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
Even terug naar je probleem, het lijkt alsof je een binaire header van een file uit wil lezen. Dit kan (met een beetje magic ;) ) ook zo:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Header
{
    public ushort Ignored;
    public ushort LastBlock;
    public ushort Blocks;
    public ushort RelocationEntries;
    public ushort ParagraphHeaderSize;
}


public static void Main()
{
    var data = new byte[] { 0x00, 0x00, 0xAA, 0xAA, 0xBB, 0xBB, 0xCC, 0xCC, 0xDD, 0xDD };
    var header = StructConverter.ToType<Header>(data);

    Console.WriteLine($"LastBlock 0x{header.LastBlock:X}");
    Console.WriteLine($"Blocks 0x{header.Blocks:X}");
    Console.WriteLine($"RelocationEntries 0x{header.RelocationEntries:X}");
    Console.WriteLine($"ParagraphHeaderSize 0x{header.ParagraphHeaderSize:X}");
}



En het beetje magic wat je nodig hebt is een converter die de byte array omzet naar je struct:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static class StructConverter
{
    public static byte[] ToArray<T>(T data)
    {
        int size = Marshal.SizeOf(data);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(data, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);

        return arr;
    }

    public static T ToType<T>(byte[] data)
    {
        int sz = Marshal.SizeOf(typeof(T));
        IntPtr ptr = Marshal.AllocHGlobal(sz);
        Marshal.Copy(data, 0, ptr, sz);
        T result = (T)Marshal.PtrToStructure(ptr, typeof(T));
        Marshal.FreeHGlobal(ptr);
        return result;
    }
}

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
DonJunior schreef op woensdag 16 september 2015 @ 12:00:
Dat ben ik met je eens. Zie? Zo komt het ook voor mij wat logischer over dan alleen je opmerking 'Really'
Ik heb namelijk altijd geleerd dat je IO operaties eigenlijk altijd asynchroon moet doen zodat (bij een wat langere response tijd) de interface niet blijft hangen. Dat was dan ook de enige opmerking die ik maakte. Hoe dit toe te passen is aan de TS zelf natuurlijk. :)
De opmerking was ongenuanceerd, omdat je uitspraak ook ongenuanceerd was. Maar ik begrijp nu waarom dat komt, n.l. omdat je geleerd hebt dat IO operaties "eigenlijk altijd asynchroon" moeten; dat is n.l. veel te simplistisch gesteld.

Ga maar na, als ik in de praktijk bij een IO operatie 1 ms moet wachten (en dus de UI blokkeer), moet ik dan moeite gaan steken in het asynchroon maken van die operatie? En daarbij ook misschien nog rekening moet gaan houden met synchronisatie, re-entrancy en wat er nog meer bij kan komen kijken?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • DonJunior
  • Registratie: Februari 2008
  • Laatst online: 21:59
farlane schreef op woensdag 16 september 2015 @ 14:12:
[...]

De opmerking was ongenuanceerd, omdat je uitspraak ook ongenuanceerd was. Maar ik begrijp nu waarom dat komt, n.l. omdat je geleerd hebt dat IO operaties "eigenlijk altijd asynchroon" moeten; dat is n.l. veel te simplistisch gesteld.

Ga maar na, als ik in de praktijk bij een IO operatie 1 ms moet wachten (en dus de UI blokkeer), moet ik dan moeite gaan steken in het asynchroon maken van die operatie? En daarbij ook misschien nog rekening moet gaan houden met synchronisatie, re-entrancy en wat er nog meer bij kan komen kijken?
Waarschijnlijk interpreteer ik het fout, maar je komt echt heel arrogant over zo, alsof je alles al weet en niemand jou meer iets kan vertellen. Ik gaf alleen maar als tip om de IO operaties asynchroon te schrijven i.v.m blocking UI hoezo is dat ongenuanceerd?

Je gaat er bij voorbaat al vanuit dat je IO operaties altijd goed gaan.. Dat lijkt me niet de insteek die je moet hebben bij programmeren. Want in dat geval hoef je ook nooit try/catch blokken te schrijven toch?

Nah goed, we gaan offtopic dus ik laat het hier maar bij.

*sowieso


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
DonJunior schreef op woensdag 16 september 2015 @ 16:32:
Waarschijnlijk interpreteer ik het fout, maar je komt echt heel arrogant over zo, alsof je alles al weet en niemand jou meer iets kan vertellen.
Dat is niet mijn bedoeling en daar was ik me ook niet van bewust. Waar ik me wel heel duidelijk van bewust ben is dat ik bij lange na niet "alles weet", maar sommige dingen weet ik weer wel.
Je gaat er bij voorbaat al vanuit dat je IO operaties altijd goed gaan.
Ik ga er niet van uit dat alles bij voorbaat goed gaat, waar lees je dat?
Dat lijkt me niet de insteek die je moet hebben bij programmeren. Want in dat geval hoef je ook nooit try/catch blokken te schrijven toch?
Kun je me uitleggen wat het verband is tussen het al dan niet asynchroon doen van IO operaties met het optreden van fouten en de afhandeling daarvan te maken heeft?
Nah goed, we gaan offtopic dus ik laat het hier maar bij
ik heb het idee dat er meer (beginnende) software engineers zijn die denken dat alles asynchroon maken een doel op zich is, dus de discussie is op zich wel relevant.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1