<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Udvikling</title><link>http://activedeveloper.dk/weblogs/mrjs/category/7.aspx</link><description>Udvikling</description><managingEditor>Jesper Jensen</managingEditor><dc:language>da-DK</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Jesper Jensen</dc:creator><title>Simpel logning til tekstfil</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2006/05/04/2812.aspx</link><pubDate>Thu, 04 May 2006 11:40:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2006/05/04/2812.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2812.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2006/05/04/2812.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2812.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2812.aspx</trackback:ping><description>&lt;p&gt;Ja - jeg ved det: Der findes en super fed &lt;a href="http://msdn.microsoft.com/practices/guidetype/AppBlocks/default.aspx?pull=/library/en-us/dnpag2/html/ehab.asp"&gt;applikationsblok&lt;/a&gt; der kan håndtere og opfylde alle mulige ønsker til opsamling af undtagelser og beskeder i en applikation. Det er bare ikke altid at behovet er så stort, og det er ofte man kan klare sig med langt mindre end denne mastodont tilbyder. Jeg har derfor ofte brugt en letvægts-klasse jeg har fremstillet til formålet. Den har i al sin enkelthed bestået af 4-500 liniers kode, og har håndteret skrivning af strenge til en logfil i tekstformat. Alt sammen meget fint, men så var det lige jeg faldt over en ny statisk metode på &lt;em&gt;File &lt;/em&gt;klassen&lt;em&gt; &lt;/em&gt;i 2.0 frameworket: File.AppendAllText&lt;/p&gt;
&lt;p&gt;Nu kan min simple logger klasse blive endnu mere simpel. Metoden tage 2 argumenter: strengen der skal skrives og stien til filen der skal skrives i. Findes filen i forvejen bliver der tilføjet til den, findes den ikke, oprettes en ny. Al håndtering af de underliggende streams bliver udført af metoden - ikke noget med irriterende file-locks fordi man glemmer at flushe sin textstream - nice. Her er min applikationsblok:&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: #ffffff; COLOR: black; FONT-FAMILY: Consolas"&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;    7&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;    &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;public&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;class&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Logger&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;    8&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;    {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;    9&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;private&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; Logger()&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   10&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   11&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   12&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   13&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;private&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; LOGFILE = &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: maroon"&gt;"log.txt"&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   14&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   15&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;public&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;void&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; Publish(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Exception&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; e)&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   16&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   17&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            Write(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Format(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: maroon"&gt;"{0}{2}\t\t{1}"&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;, e.Message, e.StackTrace, &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Environment&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.NewLine), &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;EventLogEntryType&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Error);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   18&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   19&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   20&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;public&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;void&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; Publish(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; message)&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   21&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   22&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            Write(message, &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;EventLogEntryType&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Information);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   23&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   24&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   25&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;private&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;void&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; Write(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; message, &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;EventLogEntryType&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; type)&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   26&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   27&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   28&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   29&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; contents =&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   30&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Format(&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   31&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: maroon"&gt;"{0}\t{1}\t{2}{3}"&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   32&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;DateTime&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Now,&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   33&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    type,&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   34&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    message,&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   35&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Environment&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.NewLine&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   36&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                    );&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   37&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;                &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;File&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.AppendAllText(LOGFILE, contents);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   38&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   39&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;finally&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; { }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   40&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   41&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;    }&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Thats it - 40 linier!&lt;/p&gt;
&lt;p&gt;Code on...&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2812.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Ja - jeg ved det: Der findes en super fed <a href="http://msdn.microsoft.com/practices/guidetype/AppBlocks/default.aspx?pull=/library/en-us/dnpag2/html/ehab.asp">applikationsblok</a> der kan håndtere og opfylde alle mulige ønsker til opsamling af undtagelser og beskeder i en applikation. Det er bare ikke altid at behovet er så stort, og det er ofte man kan klare sig med langt mindre end denne mastodont tilbyder. Jeg har derfor ofte brugt en letvægts-klasse jeg har fremstillet til formålet. Den har i al sin enkelthed bestået af 4-500 liniers kode, og har håndteret skrivning af strenge til en logfil i tekstformat. Alt sammen meget fint, men så var det lige jeg faldt over en ny statisk metode på <em>File </em>klassen<em> </em>i 2.0 frameworket: File.AppendAllText</p>
<p>Nu kan min simple logger klasse blive endnu mere simpel. Metoden tage 2 argumenter: strengen der skal skrives og stien til filen der skal skrives i. Findes filen i forvejen bliver der tilføjet til den, findes den ikke, oprettes en ny. Al håndtering af de underliggende streams bliver udført af metoden - ikke noget med irriterende file-locks fordi man glemmer at flushe sin textstream - nice. Her er min applikationsblok:</p>
<div style="FONT-SIZE: 10pt; BACKGROUND: #ffffff; COLOR: black; FONT-FAMILY: Consolas">
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">    7</span> <span style="BACKGROUND: white">    </span><span style="BACKGROUND: white; COLOR: blue">public</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">class</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: teal">Logger</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">    8</span> <span style="BACKGROUND: white">    {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">    9</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">private</span><span style="BACKGROUND: white"> Logger()</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   10</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   11</span> <span style="BACKGROUND: white">        }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   12</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   13</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">private</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white"> LOGFILE = </span><span style="BACKGROUND: white; COLOR: maroon">"log.txt"</span><span style="BACKGROUND: white">;</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   14</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   15</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">public</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">void</span><span style="BACKGROUND: white"> Publish(</span><span style="BACKGROUND: white; COLOR: teal">Exception</span><span style="BACKGROUND: white"> e)</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   16</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   17</span> <span style="BACKGROUND: white">            Write(</span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white">.Format(</span><span style="BACKGROUND: white; COLOR: maroon">"{0}{2}\t\t{1}"</span><span style="BACKGROUND: white">, e.Message, e.StackTrace, </span><span style="BACKGROUND: white; COLOR: teal">Environment</span><span style="BACKGROUND: white">.NewLine), </span><span style="BACKGROUND: white; COLOR: teal">EventLogEntryType</span><span style="BACKGROUND: white">.Error);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   18</span> <span style="BACKGROUND: white">        }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   19</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   20</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">public</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">void</span><span style="BACKGROUND: white"> Publish(</span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white"> message)</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   21</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   22</span> <span style="BACKGROUND: white">            Write(message, </span><span style="BACKGROUND: white; COLOR: teal">EventLogEntryType</span><span style="BACKGROUND: white">.Information);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   23</span> <span style="BACKGROUND: white">        }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   24</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   25</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">private</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">void</span><span style="BACKGROUND: white"> Write(</span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white"> message, </span><span style="BACKGROUND: white; COLOR: teal">EventLogEntryType</span><span style="BACKGROUND: white"> type)</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   26</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   27</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: blue">try</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   28</span> <span style="BACKGROUND: white">            {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   29</span> <span style="BACKGROUND: white">                </span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white"> contents =</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   30</span> <span style="BACKGROUND: white">                    </span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white">.Format(</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   31</span> <span style="BACKGROUND: white">                    </span><span style="BACKGROUND: white; COLOR: maroon">"{0}\t{1}\t{2}{3}"</span><span style="BACKGROUND: white">,</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   32</span> <span style="BACKGROUND: white">                    </span><span style="BACKGROUND: white; COLOR: teal">DateTime</span><span style="BACKGROUND: white">.Now,</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   33</span> <span style="BACKGROUND: white">                    type,</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   34</span> <span style="BACKGROUND: white">                    message,</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   35</span> <span style="BACKGROUND: white">                    </span><span style="BACKGROUND: white; COLOR: teal">Environment</span><span style="BACKGROUND: white">.NewLine</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   36</span> <span style="BACKGROUND: white">                    );</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   37</span> <span style="BACKGROUND: white">                </span><span style="BACKGROUND: white; COLOR: teal">File</span><span style="BACKGROUND: white">.AppendAllText(LOGFILE, contents);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   38</span> <span style="BACKGROUND: white">            }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   39</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: blue">finally</span><span style="BACKGROUND: white"> { }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   40</span> <span style="BACKGROUND: white">        }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   41</span> <span style="BACKGROUND: white">    }</span></p></div>
<p>Thats it - 40 linier!</p>
<p>Code on...</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2812.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Det fede i de små ting</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/19/2724.aspx</link><pubDate>Wed, 19 Apr 2006 09:09:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/19/2724.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2724.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/19/2724.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2724.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2724.aspx</trackback:ping><description>&lt;p&gt;Nogen gange er det de store gennemarbejdede systemer der trigger mit hakker-gen, og gør mig grøn af misundelse over ikke at fremstille bare en lille stump af den bagvedliggende kode - (Det kunne f.eks. være &lt;a href="http://communityserver.org/"&gt;Community Server&lt;/a&gt;) . Andre gange er det bare helt små ting som smarte operatorer, eller statiske metoder på nogle af de underliggende klasser i frameworket der får mig helt op og ringe (kal mig bare nørd).&lt;/p&gt;
&lt;p&gt;Hvor tit har du skrevet følgende kode:&lt;/p&gt;&lt;code&gt;if ( str1 != null &amp;amp;&amp;amp; str1.Length&amp;gt;1)&lt;/code&gt; 
&lt;p&gt;Ja der er jo ikke andet at gøre, når man vil checke om en streng har en værdi og at den ikke er en tom streng...ind til .NET 2.0. Nu gør du bare sådan:&lt;/p&gt;&lt;code&gt;if ( !string.IsNullOrEmpty(str1))&lt;/code&gt; 
&lt;p&gt;Fedt ikke? Eller hvad med at sammenligne ord uden at tage højde for kapitalicering og stavemåde:&lt;/p&gt;&lt;code&gt;string.Compare(str1, str2, StringComparison.CurrentCultureIgnoreCase)&lt;/code&gt;
&lt;p&gt;Skulle bare lige af med det&lt;/p&gt;
&lt;p&gt;Hak'a&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2724.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Nogen gange er det de store gennemarbejdede systemer der trigger mit hakker-gen, og gør mig grøn af misundelse over ikke at fremstille bare en lille stump af den bagvedliggende kode - (Det kunne f.eks. være <a href="http://communityserver.org/">Community Server</a>) . Andre gange er det bare helt små ting som smarte operatorer, eller statiske metoder på nogle af de underliggende klasser i frameworket der får mig helt op og ringe (kal mig bare nørd).</p>
<p>Hvor tit har du skrevet følgende kode:</p><code>if ( str1 != null &amp;&amp; str1.Length&gt;1)</code> 
<p>Ja der er jo ikke andet at gøre, når man vil checke om en streng har en værdi og at den ikke er en tom streng...ind til .NET 2.0. Nu gør du bare sådan:</p><code>if ( !string.IsNullOrEmpty(str1))</code> 
<p>Fedt ikke? Eller hvad med at sammenligne ord uden at tage højde for kapitalicering og stavemåde:</p><code>string.Compare(str1, str2, StringComparison.CurrentCultureIgnoreCase)</code>
<p>Skulle bare lige af med det</p>
<p>Hak'a</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2724.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Når C# bliver rigtig simpelt</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/10/2667.aspx</link><pubDate>Mon, 10 Apr 2006 21:46:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/10/2667.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2667.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2006/04/10/2667.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2667.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2667.aspx</trackback:ping><description>&lt;p&gt;Jeg er af den type der godt kan lide at komprimerer min kode, så den bliver så simpel som muligt. Derfor elsker jeg de nye operatorer i .NET 2.0 - Så som en &lt;i&gt;??&lt;/i&gt;, der gør variabel tildeling til en leg.&lt;/p&gt;&lt;code&gt;object mitresultat = minvariabe ?? alternativ;&lt;/code&gt; 
&lt;p&gt;Jeg synes simpelthen bare det er cool kode, uanset hvad andre så end mener om læsbarheden o.s.v. &lt;br /&gt;Jeg faldt over en bagside artikel i et gammelt MSDN Magazin, der var skrevet af Don Box - &lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/10/EndBracket/default.aspx"&gt;link&lt;/a&gt;. I artiklen filosoferer han om forelskelse i dynamiske sprog som Ruby og ikke mindst Lisp. Ikke overraskende runder han artiklen af med at demonstrerer hvordan Generics og anonyme metoder, har gjort C# i stand til at efterkomme nogle af de fordele som der er ved dynamiske sprog. Prøv lige at se her: &lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: #e6e6e6; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;    9&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;void&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; Main(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;[] args)&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   10&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   11&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Converter&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;&amp;lt;&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;, &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;&amp;gt; adder = MakeAccumulator();&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   12&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   13&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; result = adder(10);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   14&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Console&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.WriteLine(result);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   15&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            result = adder(5);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   16&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Console&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.WriteLine(result);&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   17&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   18&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Console&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;.Read();&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   19&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   20&lt;/span&gt; &lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   21&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;static&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: teal"&gt;Converter&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;&amp;lt;&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;, &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;&amp;gt; MakeAccumulator()&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   22&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        {&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   23&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; total = 0;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   24&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;            &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;return&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;delegate&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt;(&lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; x) { &lt;/span&gt;&lt;span style="BACKGROUND: white; COLOR: blue"&gt;return&lt;/span&gt;&lt;span style="BACKGROUND: white"&gt; total += x; };&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;&lt;span style="COLOR: #2b91af"&gt;   25&lt;/span&gt; &lt;span style="BACKGROUND: white"&gt;        }&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;!--EndFragment--&gt;
&lt;p&gt;Læg mærke til at man ikke behøver at erklærer sine variabler i metode delegaten, da den er underforstået af kontekst. Det er sgu da cool når man lyn hurtigt vil havde noget kode til at virke, og ikke orker at designe et business-objekt med alt hvad der af følger - 123 og man er kørende. Det elsker jeg...&lt;/p&gt;
&lt;p&gt;Code on&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2667.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Jeg er af den type der godt kan lide at komprimerer min kode, så den bliver så simpel som muligt. Derfor elsker jeg de nye operatorer i .NET 2.0 - Så som en <i>??</i>, der gør variabel tildeling til en leg.</p><code>object mitresultat = minvariabe ?? alternativ;</code> 
<p>Jeg synes simpelthen bare det er cool kode, uanset hvad andre så end mener om læsbarheden o.s.v. <br />Jeg faldt over en bagside artikel i et gammelt MSDN Magazin, der var skrevet af Don Box - <a href="http://msdn.microsoft.com/msdnmag/issues/05/10/EndBracket/default.aspx">link</a>. I artiklen filosoferer han om forelskelse i dynamiske sprog som Ruby og ikke mindst Lisp. Ikke overraskende runder han artiklen af med at demonstrerer hvordan Generics og anonyme metoder, har gjort C# i stand til at efterkomme nogle af de fordele som der er ved dynamiske sprog. Prøv lige at se her: </p>
<div style="FONT-SIZE: 10pt; BACKGROUND: #e6e6e6; COLOR: black; FONT-FAMILY: Courier New">
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">    9</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">void</span><span style="BACKGROUND: white"> Main(</span><span style="BACKGROUND: white; COLOR: blue">string</span><span style="BACKGROUND: white">[] args)</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   10</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   11</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: teal">Converter</span><span style="BACKGROUND: white">&lt;</span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white">, </span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white">&gt; adder = MakeAccumulator();</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   12</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   13</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white"> result = adder(10);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   14</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: teal">Console</span><span style="BACKGROUND: white">.WriteLine(result);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   15</span> <span style="BACKGROUND: white">            result = adder(5);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   16</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: teal">Console</span><span style="BACKGROUND: white">.WriteLine(result);</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   17</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   18</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: teal">Console</span><span style="BACKGROUND: white">.Read();</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   19</span> <span style="BACKGROUND: white">        }</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   20</span> </p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   21</span> <span style="BACKGROUND: white">        </span><span style="BACKGROUND: white; COLOR: blue">static</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: teal">Converter</span><span style="BACKGROUND: white">&lt;</span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white">, </span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white">&gt; MakeAccumulator()</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   22</span> <span style="BACKGROUND: white">        {</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   23</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white"> total = 0;</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   24</span> <span style="BACKGROUND: white">            </span><span style="BACKGROUND: white; COLOR: blue">return</span><span style="BACKGROUND: white"> </span><span style="BACKGROUND: white; COLOR: blue">delegate</span><span style="BACKGROUND: white">(</span><span style="BACKGROUND: white; COLOR: blue">int</span><span style="BACKGROUND: white"> x) { </span><span style="BACKGROUND: white; COLOR: blue">return</span><span style="BACKGROUND: white"> total += x; };</span></p>
<p style="MARGIN: 0px"><span style="COLOR: #2b91af">   25</span> <span style="BACKGROUND: white">        }</span></p></div><!--EndFragment--><!--EndFragment-->
<p>Læg mærke til at man ikke behøver at erklærer sine variabler i metode delegaten, da den er underforstået af kontekst. Det er sgu da cool når man lyn hurtigt vil havde noget kode til at virke, og ikke orker at designe et business-objekt med alt hvad der af følger - 123 og man er kørende. Det elsker jeg...</p>
<p>Code on</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2667.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Enum datakilde til ComboBox</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2006/03/03/2350.aspx</link><pubDate>Fri, 03 Mar 2006 15:10:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2006/03/03/2350.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2350.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2006/03/03/2350.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2350.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2350.aspx</trackback:ping><description>&lt;p&gt;Jeg bruger &lt;em&gt;Enum&lt;/em&gt;'s i vid udstrækning i mine klasser, og frameworket er fyldt med Enum's. Jeg har ofte brug for at binde eet eller flere elementer fra en enum til en &lt;em&gt;ComboBox.&lt;/em&gt; Det kan for eks. være at man vil lade brugeren vælge en status (fra min egen enumeration: &lt;em&gt;FramePartState&lt;/em&gt; &lt;em&gt;).&lt;/em&gt; Enumerationen kunne se således ud:&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;code&gt;public enum FramePartState : int&lt;br /&gt;{&lt;br /&gt;  Ordered = 0,&lt;br /&gt;  LengthVerified = 1,&lt;br /&gt;  ReadyForGlue = 2,&lt;br /&gt;  Section1 = 3,&lt;br /&gt;  Section2 = 4,&lt;br /&gt;  Section3 = 5,&lt;br /&gt;  InFixture = 6,&lt;br /&gt;  Assembled = 7&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Jeg ønsker at det skal være muligt for brugeren at vælge fra denne enumeration i en &lt;em&gt;ComboBox&lt;/em&gt;. Det kan let gøres ved at bruge den statiske metode &lt;em&gt;GetNames(Type enumtype)&lt;/em&gt; på &lt;em&gt;Enum&lt;/em&gt; klassen. Metoden returnerer en array af strenge, og den kan sættes som &lt;em&gt;DataSource&lt;/em&gt; direkte på en ComboBox.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Meget fint, men jeg ønsker at kunne udelade et par af valgmulighederne, og så vil jeg gerne havde valgene vist på dansk. Desuden ville det være fedt hvis jeg kunne aflæse &lt;em&gt;SelectedValue&lt;/em&gt; egenskben direkte, uden at skulle igennem diverse SelectedIndex og array manipulationer.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Nu har jeg jo efterhånden bøvlet med .NET 2.0 i lang tid, så jeg tænker uvilkårligt på &lt;em&gt;Generics,&lt;/em&gt; som jo kan ses som en slags skabelon for kollektioner - kunne det ikke være fedt hvis der var een vi kunne bruge? Desværre - jeg har ikke kunne finde nogen (giv mig et praj hvis du har fundet een), så jeg bliver nød til at lave een selv (Jeg kunne nok nøjes med en klasse, men så ville jeg skulle skrive een for hver type enum..).&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Jeg kalder min skabelonklasse for &lt;em&gt;EnumSource.&lt;/em&gt; Selve implementeringen af klassen er simpel nok - alt hvad vi behøver er en &lt;em&gt;struct&lt;/em&gt; med 2 egenskaber &lt;em&gt;Text&lt;/em&gt; og &lt;em&gt;Value, &lt;/em&gt;hvor den første indeholder den brugervenlige tekst og den anden indeholder værdien af den aktuelle enum. Min forløbige implementering kom til at se således ud:&lt;/p&gt;&lt;code&gt;    public class EnumSource&lt;t&gt; where T : struct&lt;br /&gt;    {&lt;br /&gt;        private string _text;&lt;br /&gt;        private T _value; 
&lt;p&gt;        public EnumSource(string text, T value)&lt;br /&gt;        {&lt;br /&gt;            this._text = text;&lt;br /&gt;            this._value = value;&lt;br /&gt;        }&lt;/p&gt;
&lt;p&gt;        public string Text&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return _text;&lt;br /&gt;            }&lt;br /&gt;        }&lt;/p&gt;
&lt;p&gt;        public T Value&lt;br /&gt;        {&lt;br /&gt;            get&lt;br /&gt;            {&lt;br /&gt;                return _value;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/p&gt;&lt;/t&gt;&lt;/code&gt;
&lt;p&gt;Bemærk &lt;em&gt;generics&lt;/em&gt;-syntaksen, hvor man angiver skabelontypen imellem et sæt '&amp;lt;&amp;gt;'. Desuden har jeg begrænset (constraint) typen til kun at kunne indeholde &lt;em&gt;struct&lt;/em&gt; typer.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.3wp.dk/114139503157.JPG"&gt;&lt;br /&gt;&lt;img id="ViewPicture.ascx_GalleryImage" style="BORDER-RIGHT: black 2px solid; BORDER-TOP: black 2px solid; BORDER-LEFT: black 2px solid; WIDTH: 394px; BORDER-BOTTOM: black 2px solid; HEIGHT: 237px" alt="Enum Box" src="/weblogs//images/activedeveloper_dk/mrjs/41/r_EnumBox.JPG" /&gt; &lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bevæbnet med denne nye skabelonklasse, kan jeg nu konstruerer min datakilde på følgende måde:&lt;/p&gt;&lt;code&gt;        EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;[] states = new EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;[]&lt;br /&gt;        {&lt;br /&gt;            new EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;("Uopmålt", FramePartState.Ordered),&lt;br /&gt;            new EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;("Opmålt", FramePartState.LengthVerified),&lt;br /&gt;            new EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;("Klar til samling", FramePartState.Section1),&lt;br /&gt;            new EnumSource&lt;framepartstate&gt;&lt;framepartstate&gt;("Færdig", FramePartState.Assembled)&lt;br /&gt;        };&lt;br /&gt;        stateSelect.DataSource = states;&lt;br /&gt;        stateSelect.DisplayMember = "Text";&lt;br /&gt;        stateSelect.ValueMember = "Value";&lt;br /&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/framepartstate&gt;&lt;/code&gt;
&lt;p&gt;Sådan - nu binder jeg en enum til min &lt;em&gt;ComboBox, &lt;/em&gt;bestemmer ordlyden og udvælger et undersæt af de mulige værdier. Man kan selvfølgelig argumenterer for at min implementering er lidt firkantet, men den er uhyre flexibel, og kan tage alle enums.&lt;/p&gt;
&lt;p&gt; Lad mig høre hvis der er andre der har løst problemeatikken på andre måder (evt vha. standard klasser).&lt;/p&gt;
&lt;p&gt;Code on...&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2350.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Jeg bruger <em>Enum</em>'s i vid udstrækning i mine klasser, og frameworket er fyldt med Enum's. Jeg har ofte brug for at binde eet eller flere elementer fra en enum til en <em>ComboBox.</em> Det kan for eks. være at man vil lade brugeren vælge en status (fra min egen enumeration: <em>FramePartState</em> <em>).</em> Enumerationen kunne se således ud:</p>
<p><br /><code>public enum FramePartState : int<br />{<br />  Ordered = 0,<br />  LengthVerified = 1,<br />  ReadyForGlue = 2,<br />  Section1 = 3,<br />  Section2 = 4,<br />  Section3 = 5,<br />  InFixture = 6,<br />  Assembled = 7<br />}</code><br /></p>
<p>Jeg ønsker at det skal være muligt for brugeren at vælge fra denne enumeration i en <em>ComboBox</em>. Det kan let gøres ved at bruge den statiske metode <em>GetNames(Type enumtype)</em> på <em>Enum</em> klassen. Metoden returnerer en array af strenge, og den kan sættes som <em>DataSource</em> direkte på en ComboBox.</p>
<p><br /></p>
<p>Meget fint, men jeg ønsker at kunne udelade et par af valgmulighederne, og så vil jeg gerne havde valgene vist på dansk. Desuden ville det være fedt hvis jeg kunne aflæse <em>SelectedValue</em> egenskben direkte, uden at skulle igennem diverse SelectedIndex og array manipulationer.</p>
<p><br /></p>
<p>Nu har jeg jo efterhånden bøvlet med .NET 2.0 i lang tid, så jeg tænker uvilkårligt på <em>Generics,</em> som jo kan ses som en slags skabelon for kollektioner - kunne det ikke være fedt hvis der var een vi kunne bruge? Desværre - jeg har ikke kunne finde nogen (giv mig et praj hvis du har fundet een), så jeg bliver nød til at lave een selv (Jeg kunne nok nøjes med en klasse, men så ville jeg skulle skrive een for hver type enum..).</p>
<p><br /></p>
<p>Jeg kalder min skabelonklasse for <em>EnumSource.</em> Selve implementeringen af klassen er simpel nok - alt hvad vi behøver er en <em>struct</em> med 2 egenskaber <em>Text</em> og <em>Value, </em>hvor den første indeholder den brugervenlige tekst og den anden indeholder værdien af den aktuelle enum. Min forløbige implementering kom til at se således ud:</p><code>    public class EnumSource<t> where T : struct<br />    {<br />        private string _text;<br />        private T _value; 
<p>        public EnumSource(string text, T value)<br />        {<br />            this._text = text;<br />            this._value = value;<br />        }</p>
<p>        public string Text<br />        {<br />            get<br />            {<br />                return _text;<br />            }<br />        }</p>
<p>        public T Value<br />        {<br />            get<br />            {<br />                return _value;<br />            }<br />        }<br />    }<br /></p></t></code>
<p>Bemærk <em>generics</em>-syntaksen, hvor man angiver skabelontypen imellem et sæt '&lt;&gt;'. Desuden har jeg begrænset (constraint) typen til kun at kunne indeholde <em>struct</em> typer.<br /></p>
<p><a href="http://www.3wp.dk/114139503157.JPG"><br /><img id="ViewPicture.ascx_GalleryImage" style="BORDER-RIGHT: black 2px solid; BORDER-TOP: black 2px solid; BORDER-LEFT: black 2px solid; WIDTH: 394px; BORDER-BOTTOM: black 2px solid; HEIGHT: 237px" alt="Enum Box" src="/weblogs//images/activedeveloper_dk/mrjs/41/r_EnumBox.JPG" /> <br /><br /></a></p>
<p>Bevæbnet med denne nye skabelonklasse, kan jeg nu konstruerer min datakilde på følgende måde:</p><code>        EnumSource<framepartstate><framepartstate>[] states = new EnumSource<framepartstate><framepartstate>[]<br />        {<br />            new EnumSource<framepartstate><framepartstate>("Uopmålt", FramePartState.Ordered),<br />            new EnumSource<framepartstate><framepartstate>("Opmålt", FramePartState.LengthVerified),<br />            new EnumSource<framepartstate><framepartstate>("Klar til samling", FramePartState.Section1),<br />            new EnumSource<framepartstate><framepartstate>("Færdig", FramePartState.Assembled)<br />        };<br />        stateSelect.DataSource = states;<br />        stateSelect.DisplayMember = "Text";<br />        stateSelect.ValueMember = "Value";<br /></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></framepartstate></code>
<p>Sådan - nu binder jeg en enum til min <em>ComboBox, </em>bestemmer ordlyden og udvælger et undersæt af de mulige værdier. Man kan selvfølgelig argumenterer for at min implementering er lidt firkantet, men den er uhyre flexibel, og kan tage alle enums.</p>
<p> Lad mig høre hvis der er andre der har løst problemeatikken på andre måder (evt vha. standard klasser).</p>
<p>Code on...</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2350.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Mit VB-script mareridt II</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/10/11/2056.aspx</link><pubDate>Tue, 11 Oct 2005 14:28:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/10/11/2056.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2056.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2005/10/11/2056.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2056.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2056.aspx</trackback:ping><description>&lt;p&gt;Jeg sidder og bøvler med VB script :-)&lt;/p&gt;
&lt;p&gt;Jeg havde følgende stump kode, som fik serveren til at gå i selvsving:&lt;/p&gt;&lt;code&gt;For i=1 To Request.Form("sm").Count &lt;br /&gt;   Params(0) = Array( "@ParticipantID", adGUID, adParamInput, 16, CStr( Request.Form("sm")(i) ) )&lt;br /&gt;   Set res = GetRs( "RecordsetProcedure", Params )&lt;br /&gt;   If Not res.EOF Then &lt;br /&gt;     Response.Write( res(2) &amp;amp;"&lt;br /&gt;") &lt;br /&gt;   End If &lt;br /&gt;Next&lt;br /&gt;&lt;/code&gt;
&lt;p&gt;Hvorfor er det en uendelig løkke?&lt;br /&gt;Lad os se koden til funktionen &lt;em&gt;GetRs&lt;/em&gt; siger du nok... den er her: &lt;/p&gt;&lt;code&gt;Function GetRs( Proc, params )&lt;br /&gt;    set fp_cmd = Server.CreateObject("ADODB.Command")&lt;br /&gt;    fp_cmd.CommandText = Proc&lt;br /&gt;    fp_cmd.CommandType = adCmdStoredProc&lt;br /&gt;&lt;br /&gt;    If Not IsNull(params) Then&lt;br /&gt;    For i = 0 To UBound( params )&lt;br /&gt;        fp_cmd.Parameters.Append( fp_cmd.CreateParameter( params(i)(0), params(i)(1), params(i)(2), params(i)(3), params(i)(4) ) )&lt;br /&gt;    Next&lt;br /&gt;  End If&lt;br /&gt;  set fp_cmd.ActiveConnection = fp_conn&lt;br /&gt;  Set GetRs = fp_cmd.Execute&lt;br /&gt;End Function&lt;br /&gt;&lt;/code&gt;
&lt;p&gt;Hvad er det der er rekursivt? Ingen ting....&lt;/p&gt;
&lt;p&gt;Efter en tur i debuggeren (og uendelig tid med at isolerer problemet til denne sektion af koden), finder jeg så frem til at problemet er navnesammenfald på variablen &lt;em&gt;i&lt;/em&gt;... Variablen i har &lt;em&gt;global&lt;/em&gt; scope, og bliver altid sat til 1 ved returnering fra &lt;em&gt;GetRs&lt;/em&gt;. Dermed bliver det ydre loop aldrig forladt... Jeg ændrede så navnet fra i til x, og så virkede det som det skulle.&lt;/p&gt;
&lt;p&gt;Nu ved jeg jo ikke om det kun er programmøren der står bag den VB-kode jeg arbejder på, som er sjusket med erklæringen af variabler, eller om det er et generelt problem for &lt;em&gt;Legacy VB&lt;/em&gt; kodere, men det er da hulens umuligt at vedligeholde kode, som på den måde har globale variabler - det er simpelthen noget &lt;strong&gt;rod&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Var du klar over at uerklærede variabler i VB script har global scope?&lt;/p&gt;
&lt;p&gt;Jeg var i hvert tilfælde ikke, men det glemmer jeg aldrig igen efter dette &lt;strong&gt;&lt;a href="http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/03/709.aspx"&gt;mareridt&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2056.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Jeg sidder og bøvler med VB script :-)</p>
<p>Jeg havde følgende stump kode, som fik serveren til at gå i selvsving:</p><code>For i=1 To Request.Form("sm").Count <br />   Params(0) = Array( "@ParticipantID", adGUID, adParamInput, 16, CStr( Request.Form("sm")(i) ) )<br />   Set res = GetRs( "RecordsetProcedure", Params )<br />   If Not res.EOF Then <br />     Response.Write( res(2) &amp;"<br />") <br />   End If <br />Next<br /></code>
<p>Hvorfor er det en uendelig løkke?<br />Lad os se koden til funktionen <em>GetRs</em> siger du nok... den er her: </p><code>Function GetRs( Proc, params )<br />    set fp_cmd = Server.CreateObject("ADODB.Command")<br />    fp_cmd.CommandText = Proc<br />    fp_cmd.CommandType = adCmdStoredProc<br /><br />    If Not IsNull(params) Then<br />    For i = 0 To UBound( params )<br />        fp_cmd.Parameters.Append( fp_cmd.CreateParameter( params(i)(0), params(i)(1), params(i)(2), params(i)(3), params(i)(4) ) )<br />    Next<br />  End If<br />  set fp_cmd.ActiveConnection = fp_conn<br />  Set GetRs = fp_cmd.Execute<br />End Function<br /></code>
<p>Hvad er det der er rekursivt? Ingen ting....</p>
<p>Efter en tur i debuggeren (og uendelig tid med at isolerer problemet til denne sektion af koden), finder jeg så frem til at problemet er navnesammenfald på variablen <em>i</em>... Variablen i har <em>global</em> scope, og bliver altid sat til 1 ved returnering fra <em>GetRs</em>. Dermed bliver det ydre loop aldrig forladt... Jeg ændrede så navnet fra i til x, og så virkede det som det skulle.</p>
<p>Nu ved jeg jo ikke om det kun er programmøren der står bag den VB-kode jeg arbejder på, som er sjusket med erklæringen af variabler, eller om det er et generelt problem for <em>Legacy VB</em> kodere, men det er da hulens umuligt at vedligeholde kode, som på den måde har globale variabler - det er simpelthen noget <strong>rod</strong>.</p>
<p>Var du klar over at uerklærede variabler i VB script har global scope?</p>
<p>Jeg var i hvert tilfælde ikke, men det glemmer jeg aldrig igen efter dette <strong><a href="http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/03/709.aspx">mareridt</a></strong></p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2056.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Ny operator i C#</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/09/30/2031.aspx</link><pubDate>Fri, 30 Sep 2005 09:28:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/09/30/2031.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/2031.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2005/09/30/2031.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/2031.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/2031.aspx</trackback:ping><description>&lt;p&gt;Jeg faldt lige over en ny operator i C# version 2.0:&lt;br /&gt;
&lt;strong&gt;??&lt;/strong&gt; operatoren.&lt;br /&gt;
Den ser måske ikke ud af så meget, men den vil komme til at pryde meget af min kode fremover. Du kender måske &lt;em&gt;?:&lt;/em&gt; operatoren:&lt;/p&gt;
&lt;code&gt;object mitresultat = minvariabel!=null ? minvariabel : alternativ;&lt;/code&gt;
&lt;p&gt;&lt;em&gt;?:&lt;/em&gt; er det samme som en &lt;em&gt;if/else&lt;/em&gt; konstruktion, men jeg elsker bare at komprimerer simple betingelser på een linie. Med den nye &lt;em&gt;??&lt;/em&gt; operator, kan man komprimerer endnu mere:&lt;/p&gt;
&lt;code&gt;object mitresultat = minvariabe ?? alternativ;&lt;/code&gt;
&lt;p&gt;Det er skisme da cool! &lt;br /&gt;
Eller hvad med:
&lt;/p&gt;
&lt;code&gt;Response.Write( strMessage ?? "Uspecificeret værdi" );&lt;/code&gt;
&lt;p&gt;Man skal bare huske at operatoren kun kan bruges på &lt;em&gt;Nullable&lt;/em&gt; typer (hvilket vel er meget naturligt, når man checker for null ;-) ), og at det er en C# feature. Man kan opnå samme funktionalitet i VB.NET ved at bruge metoden &lt;em&gt;Nullable.GetValueOrDefault(defaultvalue)&lt;/em&gt;, men det er jo langt fra lige så smukt som i C#...&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms173224" title="Link til MSDN" target="_blank"&gt;Link til beskrivelse på MSDN&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Læs i øvrigt også &lt;a href="http://www.captator.dk/captator.aspx?article=160" title="Null putte" target="_blank"&gt;.Henriks artikel om Nullable typer, hvor han gennemgår den nye struktur&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2031.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Jeg faldt lige over en ny operator i C# version 2.0:<br />
<strong>??</strong> operatoren.<br />
Den ser måske ikke ud af så meget, men den vil komme til at pryde meget af min kode fremover. Du kender måske <em>?:</em> operatoren:</p>
<code>object mitresultat = minvariabel!=null ? minvariabel : alternativ;</code>
<p><em>?:</em> er det samme som en <em>if/else</em> konstruktion, men jeg elsker bare at komprimerer simple betingelser på een linie. Med den nye <em>??</em> operator, kan man komprimerer endnu mere:</p>
<code>object mitresultat = minvariabe ?? alternativ;</code>
<p>Det er skisme da cool! <br />
Eller hvad med:
</p>
<code>Response.Write( strMessage ?? "Uspecificeret værdi" );</code>
<p>Man skal bare huske at operatoren kun kan bruges på <em>Nullable</em> typer (hvilket vel er meget naturligt, når man checker for null ;-) ), og at det er en C# feature. Man kan opnå samme funktionalitet i VB.NET ved at bruge metoden <em>Nullable.GetValueOrDefault(defaultvalue)</em>, men det er jo langt fra lige så smukt som i C#...</p>
<p><a href="http://msdn2.microsoft.com/en-us/library/ms173224" title="Link til MSDN" target="_blank">Link til beskrivelse på MSDN</a></p>
<p>Læs i øvrigt også <a href="http://www.captator.dk/captator.aspx?article=160" title="Null putte" target="_blank">.Henriks artikel om Nullable typer, hvor han gennemgår den nye struktur</a></p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/2031.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>3D på den nemme måde</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/07/22/1457.aspx</link><pubDate>Fri, 22 Jul 2005 10:50:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/07/22/1457.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/1457.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2005/07/22/1457.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/1457.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/1457.aspx</trackback:ping><description>&lt;p&gt;Jeg havde den fornøjelse at arbejde med &lt;a title="DirectX Center" href="http://msdn.microsoft.com/directx/"&gt;Microsoft DirectX SDK&lt;/a&gt; for et par måneder siden, og fremstillede da et 3D view af noget vektor data. Det var forbundet med en del research, at nå ind til det væsentlige, og frembringe det ønskede resultat, men det lykkedes til sidst. SDK'en udmærker sig ved at havde en meget begrænset dokumentation, og den er mildest talt ikke for begyndere. Den forudsætter f.eks. at man ved hvad en "LookAtRH" er, og hvad den bruges til. Der er ingen forklaring hæftet på... Det lykkedes mig dog til sidst. Nu har jeg så fået endnu en opgave, som kræver en 3D fremstilling. Dog ikke den fulde shadede version, men kun en isometrisk tændstikudgave. Jeg har i den forbindelse været meget skeptisk over for at bruge Microsoft.DirectX namespacet, da jeg havde den opfattelse at det var lidt overkill på den konkrete opgave. Jeg browsede derfor rundt på nettet for at finde beskrivelser af hvordan man projekterer 3D vektore ind på en plan (det er meget længe siden jeg arbejdede med vektorer og matricer i skolen ;-) ). På den måde ville jeg så tegne iso-tegningen vha GDI+. Jeg fandt følgende: &lt;br /&gt;&lt;a title="Ryan Trudelle-Schwarz artikel om 3D projektering" href="http://authors.aspalliance.com/mamanze/articles/?p=drawing3d"&gt;Artikel der beskriver/viser projektering 3D til 2D&lt;/a&gt;&lt;br /&gt;&lt;a title="Vector Math for 3D Computer Graphics" href="http://chortle.ccsu.edu/VectorLessons/vectorIndex.html"&gt;God tutorial om 3D vektor matematik&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Der er mange flere links, men disse er efter min mening de bedste... Alle artikler, har dog en fællesnævner, og det er selvfølgelig en 4x4 matrix til at udfører selve transformeringen af koordinaterne. Alle artikler har hver deres implementering af mere eller mindre gennemførte matrix-klasser, og jeg må indrømme at jeg selv begyndte ud af den sti. Men hvorfor? Jeg synes at DirectX er overkill, og jeg ønsker i øvrigt også at viewet kan distribueres via Html, så GDI+ var løsningen til renderingen af GIF-filer. Så slog det mig: Hvorfor ikke bare udnytte Microsofts implementering af 4x4 matrix og 3D vektorer? Alle disse fede implementeringer ligger i &lt;em&gt;Microsoft.DirectX.dll&lt;/em&gt;, og de er på alle områder meget mere effektive og langt mere gennemførte end noget andet jeg har set (check evt Java implementeringen..). Vupti - jeg inkluderede namespacet, og straks havde jeg mit isometriske view renderet i GDI+.&lt;/p&gt;&lt;img src="http://www.3wp.dk/WeblogFiles/IsoView.GIF" title="Robo Visualazer Screen dump" width="672" height="529" border="0" /&gt; 
&lt;p&gt;I al sin enkelthed, så skal man blot havde en matrice der beskriver det view man ønsker:&lt;/p&gt;&lt;code&gt;Matrix view = Microsoft.DirectX.Matrix.LookAtRH(&lt;br /&gt;new Vector3(400f, 400f, 200f), // Placeringen af dit øjepunkt&lt;br /&gt;new Vector3(0.0f, 0f, 0f), // Retningen du ser imod&lt;br /&gt;new Vector3(0.0f, 0.0f, 1.0f) // Retningen du bruger som 'opad'&lt;br /&gt;); &lt;/code&gt;
&lt;p&gt;LookAtRH er en statisk metode på &lt;em&gt;Matrix&lt;/em&gt; klassen, som returnerer en matrice der beskriver: "Se på Højrehånds koordinater" (det betyder en hel del om man tolker sine koordinater som højre- eller venstrehånds koordinater). Når matricen er på plads, kan vi bare transformerer vi &lt;em&gt;Vector3&lt;/em&gt; klassens &lt;em&gt;TransformCoordinate&lt;/em&gt; metode.&lt;/p&gt;&lt;code&gt;Vector3[] points = obj.GetPoints(); // En array med 3D vektorer&lt;br /&gt;&lt;br /&gt;// Så transformerers koordinaterne&lt;br /&gt;points = Vector3.TransformCoordinate( points, view ); &lt;/code&gt;
&lt;p&gt;Her efter er det blot at tage x og y værdierne fra de enkelte vektorer, da matricen har projekteret koordinaterne ind i X - Y planen. Disse koordinater kan så plottes i et &lt;em&gt;Bitmap&lt;/em&gt; ved hjælp af GDI+&lt;/p&gt;
&lt;p&gt;Tænk at jeg overvejede at implementerer min egen Matrix-klasse... Var der ikke et ordsprog:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Gå ikke over åen efter vand.&lt;/em&gt;&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/1457.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Jeg havde den fornøjelse at arbejde med <a title="DirectX Center" href="http://msdn.microsoft.com/directx/">Microsoft DirectX SDK</a> for et par måneder siden, og fremstillede da et 3D view af noget vektor data. Det var forbundet med en del research, at nå ind til det væsentlige, og frembringe det ønskede resultat, men det lykkedes til sidst. SDK'en udmærker sig ved at havde en meget begrænset dokumentation, og den er mildest talt ikke for begyndere. Den forudsætter f.eks. at man ved hvad en "LookAtRH" er, og hvad den bruges til. Der er ingen forklaring hæftet på... Det lykkedes mig dog til sidst. Nu har jeg så fået endnu en opgave, som kræver en 3D fremstilling. Dog ikke den fulde shadede version, men kun en isometrisk tændstikudgave. Jeg har i den forbindelse været meget skeptisk over for at bruge Microsoft.DirectX namespacet, da jeg havde den opfattelse at det var lidt overkill på den konkrete opgave. Jeg browsede derfor rundt på nettet for at finde beskrivelser af hvordan man projekterer 3D vektore ind på en plan (det er meget længe siden jeg arbejdede med vektorer og matricer i skolen ;-) ). På den måde ville jeg så tegne iso-tegningen vha GDI+. Jeg fandt følgende: <br /><a title="Ryan Trudelle-Schwarz artikel om 3D projektering" href="http://authors.aspalliance.com/mamanze/articles/?p=drawing3d">Artikel der beskriver/viser projektering 3D til 2D</a><br /><a title="Vector Math for 3D Computer Graphics" href="http://chortle.ccsu.edu/VectorLessons/vectorIndex.html">God tutorial om 3D vektor matematik</a><br /></p>
<p>Der er mange flere links, men disse er efter min mening de bedste... Alle artikler, har dog en fællesnævner, og det er selvfølgelig en 4x4 matrix til at udfører selve transformeringen af koordinaterne. Alle artikler har hver deres implementering af mere eller mindre gennemførte matrix-klasser, og jeg må indrømme at jeg selv begyndte ud af den sti. Men hvorfor? Jeg synes at DirectX er overkill, og jeg ønsker i øvrigt også at viewet kan distribueres via Html, så GDI+ var løsningen til renderingen af GIF-filer. Så slog det mig: Hvorfor ikke bare udnytte Microsofts implementering af 4x4 matrix og 3D vektorer? Alle disse fede implementeringer ligger i <em>Microsoft.DirectX.dll</em>, og de er på alle områder meget mere effektive og langt mere gennemførte end noget andet jeg har set (check evt Java implementeringen..). Vupti - jeg inkluderede namespacet, og straks havde jeg mit isometriske view renderet i GDI+.</p><img src="http://www.3wp.dk/WeblogFiles/IsoView.GIF" title="Robo Visualazer Screen dump" width="672" height="529" border="0" /> 
<p>I al sin enkelthed, så skal man blot havde en matrice der beskriver det view man ønsker:</p><code>Matrix view = Microsoft.DirectX.Matrix.LookAtRH(<br />new Vector3(400f, 400f, 200f), // Placeringen af dit øjepunkt<br />new Vector3(0.0f, 0f, 0f), // Retningen du ser imod<br />new Vector3(0.0f, 0.0f, 1.0f) // Retningen du bruger som 'opad'<br />); </code>
<p>LookAtRH er en statisk metode på <em>Matrix</em> klassen, som returnerer en matrice der beskriver: "Se på Højrehånds koordinater" (det betyder en hel del om man tolker sine koordinater som højre- eller venstrehånds koordinater). Når matricen er på plads, kan vi bare transformerer vi <em>Vector3</em> klassens <em>TransformCoordinate</em> metode.</p><code>Vector3[] points = obj.GetPoints(); // En array med 3D vektorer<br /><br />// Så transformerers koordinaterne<br />points = Vector3.TransformCoordinate( points, view ); </code>
<p>Her efter er det blot at tage x og y værdierne fra de enkelte vektorer, da matricen har projekteret koordinaterne ind i X - Y planen. Disse koordinater kan så plottes i et <em>Bitmap</em> ved hjælp af GDI+</p>
<p>Tænk at jeg overvejede at implementerer min egen Matrix-klasse... Var der ikke et ordsprog:<br /><br /><em>Gå ikke over åen efter vand.</em></p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/1457.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>XmlHttp og sikkerhed i IE</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/21/999.aspx</link><pubDate>Tue, 21 Jun 2005 12:37:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/21/999.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/999.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/21/999.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/999.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/999.aspx</trackback:ping><description>&lt;p&gt;Selv om der er mange der gør et stort nummer ud af at nedgøre &lt;a title="Asynkron JavaScript XMLHttp" href="http://www.adaptivepath.com/publications/essays/archives/000385.php"&gt;AJaX&lt;/a&gt; og fortælle om hvor længe det har været mulig, kan man ikke komme uden om at det er en teknologi der er modnet på det sidste. Ja - det har kunne lade sig gøre siden IE 4, og det har aldrig vundet indpas. Flere ting, har bragt arkitekturen tilbage på banen igen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firefox og Mozilla implementerer XmlHttp objektet, så man har ikke længere problemet med platformafhængigheden 
&lt;/li&gt;&lt;li&gt;Båndbredden er generelt blevet 10x bedre siden IE4 &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Alt i alt har det givet os en bedre oplevelse ved brug af webapplikationer, men der er en ting man lige skal skrive sig bag øret, når man nu går i gang med at implementerer &lt;a title="Asynkron JavaScript XMLHttp" href="http://www.adaptivepath.com/publications/essays/archives/000385.php"&gt;AJaX&lt;/a&gt; (eller ICallBackEventHandler i ASP.NET 2.0).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cross domain issue&lt;/strong&gt; - Hvis man har en Html-kontrol, som laver en XmlHttp forespørgsel til en service på et andet domæne, som er tilføjet listen af &lt;em&gt;Trusted Sites&lt;/em&gt;, vil man blive promptet for sikkerheds risikoen. Det samme gælder hvis man har applikationen liggende på det lokale netværk, og kontrollen kalder ud på internettet. Det kan f.eks. være aktuelt, hvis du har implementeret Google search eller RSS reader i sin applikation.&lt;/p&gt;
&lt;p&gt;Man får disse problemer ved forespørgsler på tværs af sikkerheds-zoner, og man kan selvfølgelig komme uden om det ved at tilføje de forskellige services til sin liste med websteder man har tillid til. Jeg vil ikke anbefale den fremgangsmåde, da man på den måde forlanger at brugerne skal havde tillid til en 'fremmed' service, som man ikke selv har indflydelse på. Kan du f.eks. garanterer at det ikke er forbundet med fare at kalde services på Google eller Amazon? Nej vel. Løsningen på problemet vil være at lave en WebService proxy-metode på domænet der kalder servicen. På den måde åbner du kun for det du har brug for, og du kan, hvis sikkerhed er højt prioriteret, validerer responsen fra servicen inden den afsendes til klienten.&lt;/p&gt;&lt;img title="Mit whiteboard" height="223" src="http://www.3wp.dk/WeblogFiles/050621_122936.gif" width="297" border="0" /&gt; 
&lt;p&gt;Link MSDN:&lt;a title="Link til dokumentation på MSDN" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/9ad3c67d-6695-42cf-95fb-0310d0950a06.asp"&gt; XmlClient Security&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/999.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Selv om der er mange der gør et stort nummer ud af at nedgøre <a title="Asynkron JavaScript XMLHttp" href="http://www.adaptivepath.com/publications/essays/archives/000385.php">AJaX</a> og fortælle om hvor længe det har været mulig, kan man ikke komme uden om at det er en teknologi der er modnet på det sidste. Ja - det har kunne lade sig gøre siden IE 4, og det har aldrig vundet indpas. Flere ting, har bragt arkitekturen tilbage på banen igen:</p>
<ul>
<li>Firefox og Mozilla implementerer XmlHttp objektet, så man har ikke længere problemet med platformafhængigheden 
</li><li>Båndbredden er generelt blevet 10x bedre siden IE4 </li></ul>
<p>Alt i alt har det givet os en bedre oplevelse ved brug af webapplikationer, men der er en ting man lige skal skrive sig bag øret, når man nu går i gang med at implementerer <a title="Asynkron JavaScript XMLHttp" href="http://www.adaptivepath.com/publications/essays/archives/000385.php">AJaX</a> (eller ICallBackEventHandler i ASP.NET 2.0).</p>
<p><strong>Cross domain issue</strong> - Hvis man har en Html-kontrol, som laver en XmlHttp forespørgsel til en service på et andet domæne, som er tilføjet listen af <em>Trusted Sites</em>, vil man blive promptet for sikkerheds risikoen. Det samme gælder hvis man har applikationen liggende på det lokale netværk, og kontrollen kalder ud på internettet. Det kan f.eks. være aktuelt, hvis du har implementeret Google search eller RSS reader i sin applikation.</p>
<p>Man får disse problemer ved forespørgsler på tværs af sikkerheds-zoner, og man kan selvfølgelig komme uden om det ved at tilføje de forskellige services til sin liste med websteder man har tillid til. Jeg vil ikke anbefale den fremgangsmåde, da man på den måde forlanger at brugerne skal havde tillid til en 'fremmed' service, som man ikke selv har indflydelse på. Kan du f.eks. garanterer at det ikke er forbundet med fare at kalde services på Google eller Amazon? Nej vel. Løsningen på problemet vil være at lave en WebService proxy-metode på domænet der kalder servicen. På den måde åbner du kun for det du har brug for, og du kan, hvis sikkerhed er højt prioriteret, validerer responsen fra servicen inden den afsendes til klienten.</p><img title="Mit whiteboard" height="223" src="http://www.3wp.dk/WeblogFiles/050621_122936.gif" width="297" border="0" /> 
<p>Link MSDN:<a title="Link til dokumentation på MSDN" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/9ad3c67d-6695-42cf-95fb-0310d0950a06.asp"> XmlClient Security</a></p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/999.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Mit VB mareridt</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/03/709.aspx</link><pubDate>Fri, 03 Jun 2005 15:10:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/06/03/709.aspx</guid><description>My Nightmar on VB Street&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/709.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Mit job som freelance udvikler, bringer mig langt omkring! Jeg sidder i øjeblikket med en forholdsvis stor applikation, som er lavet i ASP 3.0 ... med VB som server script!!! Det er da helt enormt hvor svært det er at debugge i det skidt. Man kan dybest set tillade sig alt:</p>
<ul>
<li>skrive med store og små bogstaver i en uendelighed 
</li><li>Ændre type på variabler 
</li><li>Multiplicerer et serverobjekt med en variant og dividerer et heltal (se screendump) 
</li><li>Den værste <strong>On Error Resume Next</strong> </li></ul><img title="VB script nightmare" height="160" src="http://www.3wp.dk/WeblogFiles/030605_VBNightmare.gif" width="565" border="0" /> 
<p>Hvor er jeg glad for et typestærkt udviklingsmiljø.</p>
<p>God weekend</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/709.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Jesper Jensen</dc:creator><title>Ny artikel: Javascript og OOP</title><link>http://activedeveloper.dk/weblogs/mrjs/archive/2005/05/26/631.aspx</link><pubDate>Thu, 26 May 2005 08:17:00 GMT</pubDate><guid>http://activedeveloper.dk/weblogs/mrjs/archive/2005/05/26/631.aspx</guid><wfw:comment>http://activedeveloper.dk/weblogs/mrjs/comments/631.aspx</wfw:comment><comments>http://activedeveloper.dk/weblogs/mrjs/archive/2005/05/26/631.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://activedeveloper.dk/weblogs/mrjs/comments/commentRss/631.aspx</wfw:commentRss><trackback:ping>http://activedeveloper.dk/weblogs/mrjs/services/trackbacks/631.aspx</trackback:ping><description>&lt;p&gt;Er OOP i Javascript mulig? Set ud fra dagens standarder med JScript.NET, VB.NET og C# som jo er 100% objekt orienterede, kan det se ud til at være en umulig opgave. Jeg var engang en haj til Javascript, så derfor har jeg forsøgt at genopdage syntaksen, og vil med denne artikel gennemgå princippet i at oprette arv i Javascript kode. Det er og bliver jo det klare valg, når man skal producerer kode på klienten i enhver web-applikation, og med ASP.NET webkontroller er behovet for robust klientside kode bare endnu større.&lt;/p&gt;
&lt;p&gt;Læs artiklen: &lt;a href="http://activedeveloper.dk/weblogs/mrjs/articles/629.aspx"&gt;Javascript og OOP &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;...og så lige til sidst: En glemt men uvurdelig metode fra &lt;a href="http://aspnet.4guysfromrolla.com/articles/052505-1.aspx"&gt;4 guys&lt;/a&gt; - det er da muligt at Scott har glemt/overset denne her metode:&lt;/p&gt;&lt;code&gt;string completePath = System.IO.Path.Combine(@"C:\MyApp\", @"\Images\Skyline.jpg"); &lt;/code&gt;
&lt;p&gt;men jeg har nu brugt den mange gange - selv i ASP 3.0:&lt;/p&gt;&lt;code&gt;var Fso = Server.CreateObject( "Scripting.FileSystemObject" );&lt;br /&gt;var fullpath = Fso.BuildPath( "C:\\MyApp\\", "\\Images\\Skyline.jpg" ); &lt;/code&gt;
&lt;p&gt;Anyway - det ser ud til at der kommer en serie af artikler fra den kant med fokus på 'glemte/oversete' metoder i baseklasserne. Første artikel er som altid; &lt;a href="http://aspnet.4guysfromrolla.com/articles/052505-1.aspx"&gt;seværdig&lt;/a&gt;, så check den ud.&lt;/p&gt;&lt;img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/631.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Er OOP i Javascript mulig? Set ud fra dagens standarder med JScript.NET, VB.NET og C# som jo er 100% objekt orienterede, kan det se ud til at være en umulig opgave. Jeg var engang en haj til Javascript, så derfor har jeg forsøgt at genopdage syntaksen, og vil med denne artikel gennemgå princippet i at oprette arv i Javascript kode. Det er og bliver jo det klare valg, når man skal producerer kode på klienten i enhver web-applikation, og med ASP.NET webkontroller er behovet for robust klientside kode bare endnu større.</p>
<p>Læs artiklen: <a href="http://activedeveloper.dk/weblogs/mrjs/articles/629.aspx">Javascript og OOP </a></p>
<p>...og så lige til sidst: En glemt men uvurdelig metode fra <a href="http://aspnet.4guysfromrolla.com/articles/052505-1.aspx">4 guys</a> - det er da muligt at Scott har glemt/overset denne her metode:</p><code>string completePath = System.IO.Path.Combine(@"C:\MyApp\", @"\Images\Skyline.jpg"); </code>
<p>men jeg har nu brugt den mange gange - selv i ASP 3.0:</p><code>var Fso = Server.CreateObject( "Scripting.FileSystemObject" );<br />var fullpath = Fso.BuildPath( "C:\\MyApp\\", "\\Images\\Skyline.jpg" ); </code>
<p>Anyway - det ser ud til at der kommer en serie af artikler fra den kant med fokus på 'glemte/oversete' metoder i baseklasserne. Første artikel er som altid; <a href="http://aspnet.4guysfromrolla.com/articles/052505-1.aspx">seværdig</a>, så check den ud.</p><img src ="http://activedeveloper.dk/weblogs/mrjs/aggbug/631.aspx" width = "1" height = "1" /></body></item></channel></rss>