<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martijn's C# Programming Blog &#187; Chapter</title>
	<atom:link href="http://www.dijksterhuis.org/category/csharp/chapter/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dijksterhuis.org</link>
	<description>Information, news about programming in C#</description>
	<lastBuildDate>Fri, 07 Aug 2009 21:26:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Exploring C# Boxing</title>
		<link>http://www.dijksterhuis.org/exploring-boxing/</link>
		<comments>http://www.dijksterhuis.org/exploring-boxing/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 07:29:49 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Chapter]]></category>
		<category><![CDATA[Learn C#]]></category>
		<category><![CDATA[boxing]]></category>

		<guid isPermaLink="false">http://www.dijksterhuis.org/?p=908</guid>
		<description><![CDATA[Boxing in C# has little to do with Saturday night television but quite a bit more with that part-time job at the warehouse you had as a student. It is an important concept in C# that is related to how the compiler handles different kinds of variables in memory. Knowing how the compiler handles the [...]<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.dijksterhuis.org/wp-content/uploads/2009/03/boxes2.jpg" alt="C# Boxing Explained" title="C# Boxing Explained" width="570" height="246" class="alignleft size-full wp-image-934" /></p>
<p><em>Boxing in C# has little to do with Saturday night television but quite a bit more with that part-time job at the warehouse you had as a student. It is an important concept in C# that is related to how the compiler handles different kinds of variables in memory. Knowing how the compiler handles the various types allows you to avoid unexpected side effects in your code. </em></p>
<p>This article explains what boxing is, how it works and how it can negatively effect your code if you don&#8217;t pay attention to it. We also look at how generics can be used to improve your code&#8217;s efficiency. And we try to answer the ultimate question: Is everything in C# an object?</p>
<p><span id="more-908"></span></p>
<h3>Everything is an object in C# .. but not all objects are created equally</h3>
<p>In C#, everything inherits from System.Object, so they share all the common object methods :</p>
<blockquote><p>
string a = &#8220;hello world&#8221;;<br />
int     b = 34;<br />
Console.WriteLine( &#8220;{0} {1}&#8221;,a.ToString(),b.ToString());
</p></blockquote>
<p>At first glance all objects look the same in C#. But an important distinction is made between <em>value types</em> and <em>reference types</em>. Value types are basic types such as <em>struct</em>, <em>int</em>, <em>long</em>, <em>short</em> etc. Reference types are all the classes you will use (strings, delegates, objects)</p>
<ul>
<li>Value types (int,struct..) etc are located on the stack. (unless they are part of a reference type, such as a class)</li>
<li>Reference types (classes&#8230;) are accessed through a pointer to their actual location on the heap.</li>
</ul>
<p>We simplify things a little for this article: The stack keeps track of what is executing in our application. As we enter and exit methods items are added to or removed from the top. The heap stores all the applications data, and since data can be added to and removed from it randomly it needs to be garbage collected.</p>
<p>Why the difference ? The stack is faster to access for the runtime so by putting simple types close at hand the code gains in efficiency.</p>
<p><strong>Assigning variables</strong></p>
<p><img src="http://www.dijksterhuis.org/wp-content/uploads/2009/03/boxing.png" alt="C# Boxing" title="C# Boxing" width="250" height="261" class="alignleft size-full wp-image-920" />The graphic shows four possible scenarios :</p>
<ol>
<li><strong>Boxing: </strong>When you assign an integer to an object (object b=a): a new managed memory block is created on the heap. For this C# has to allocate memory at runtime.</li>
<li><strong>By Value: </strong>If you copy the integer to another integer (int c=a) the value is simply copied to another memory slot on the stack (which is allocated at compile time), this is the fastest assignment as most checks can be done at compile time.</li>
<li><strong>Unboxing:</strong> When you cast an object to a value type (d=(int)b) the result is stored on the stack. This is also an expensive operation as at runtime the value has to be retrieved from the heap and is then checked to see if the cast was valid. (If the source argument is null or a reference to an incompatible object, an<strong> InvalidCastException</strong> is thrown.)</li>
<li><strong>By Reference: </strong>Classes are reference types so if you assign a new object to an older object (object e = b) no new instance is created, the object pointer on the stack simply points to the older object. A direct result of this is that if you modify either b or e, they will both reflect the change as they both point to the same location in memory.</li>
</ol>
<p>Boxing is as simply putting a basic type in wrapper (making it a fully blown object), and unboxing taking that wrapped object and converts it back to a simpler type. To do the boxing managed memory needs to be allocated on the heap, references need to be updated, and the contents of the value type have to be copied. </p>
<p><strong>Value types are copied, reference types just refer to the original object</strong></p>
<p>The following code example shows how a simple change in code can have very different results.</p>
<div>
<table border="1" cellspacing="0" cellpadding="3" width="100%">
<tbody>
<tr>
<td width="50%"><strong>Example A</strong></td>
<td width="50%"><strong>Example B</strong></td>
</tr>
<tr>
<td width="50%">
<pre class="brush: c#">
    class MainClass
    {
        struct Demo
        {
            public int x;
            public Demo(int x)
            {
                this.x = x;
            }
        }

        public static void Main(string[] args)
        {
            Demo p = new Demo(10);
            object box = p;
            p.x = 20;
            Console.Write(((Demo)box).x);
        }
    }
</pre>
</td>
<td width="50%">
<pre class="brush: c#">
   class MainClass
    {
        class Demo
        {
            public int x;
            public Demo(int x)
            {
                this.x = x;
            }
        }

        public static void Main(string[] args)
        {
            Demo p = new Demo(10);
            object reference = p;
            p.x = 20;
            Console.Write(((Demo)reference).x);
        }
    }
</pre>
</td>
</tr>
<tr>
<td width="50%">Result: 10</td>
<td width="50%">Result: 20</td>
</tr>
</tbody>
</table>
</div>
<p>In Example A, because Demo is a struct (and thus a value type on the stack) when we box it a copy is made. When we modify the original no change is made to the copy.</p>
<p>In Example B, we have created Demo as a class. In this situation we can assign it to another object and we don&#8217;t need to box it. A reference is made instead. So when we update the original, the copy is also updated as they both point to the same location in memory.</p>
<h3>Boxing and unboxing value types slows things down</h3>
<p>Often you can&#8217;t rely on what the type of variable a function will take so you need to use an object variable as object is the lowest common denominator in .NET. In the following example we use the <em>ArrayList</em> class to store a set of integers. The <em>ArrayList</em> can store any type of variable, but to be able to do this it accept the <em>object</em> class. </p>
<pre class="brush: c#">
        using System.Collections;

        public static void Main(string[] args)
        {
            int total = 0;
            ArrayList myList = new ArrayList();
            for (int Lp = 0; Lp &lt; 10000000; Lp++)
                myList.Add(Lp); // Box: Integer to an object
            foreach(object item in myList)
                total += (int)item; // Unbox: Object to integer
        }
</pre>
<p>When we add an integer to the Arraylist it is boxed into an object, and when we retrieve it it is unboxed back into an integer.</p>
<p>Note that this is only an issue if we are trying to store value types in the arraylist. If we were trying to store objects (eg. classes) there is no boxing done, as the original type was an object already. In this situation a simple reference is stored. On retrieval there is no unboxing necessary as only a reference is returned.</p>
<h3>Boxing in Action</h3>
<p>When we look at our code in a dissassembler the boxing operation is clearly visible in the output stream:</p>
<blockquote><p>
;<em> myList.Add(Lp); // Box: Integer to an object</em><br />
IL_000f:  ldloc.1<br />
IL_0010:  ldloc.2<br />
IL_0011:  box [mscorlib]System.Int32<br />
IL_0016:  callvirt instance int32 class [mscorlib]System.Collections.ArrayList::Add(object)
</p></blockquote>
<p>And when we convert the object back to an integer the reverse happens:</p>
<blockquote><p>
; total += (int)item; <strong>// Unbox: Object to integer</strong><br />
IL_0042:  unbox [mscorlib]System.Int32
</p></blockquote>
<h3>Generics remove the need to box and unbox value types</h3>
<p>In .NET 2.0 generics and generic collections were introduced that remove the need to box and unbox variables in many common situations. The following example is functionally equivalent to the earlier boxing example. We use a generic here, but force it to be &#8220;object&#8221;:</p>
<pre class="brush: c#">
        using System.Collections.Generic;
        public static void Main(string[] args)
        {
            int total = 0;
            List&lt;object&gt; myList = new List&lt;object&gt;();
            for (int Lp = 0; Lp &lt; 10000000; Lp++)
                myList.Add((object)Lp); // We need a boxing operation
            foreach(int item in myList)
                total += (int)item; // Unbox back to an int
        }
</pre>
<p>The above example of course makes little sense because we are inefficient on purpose. I included it to demonstrate how with generics we can get around the need for boxing with generic collections.</p>
<pre class="brush: c#">
        using System.Collections.Generic;
        public static void Main(string[] args)
        {
            int total = 0;
            List&lt;int&gt; myList = new List&lt;int&gt;();
            for (int Lp = 0; Lp &lt; 10000000; Lp++)
                myList.Add(Lp); // No need to box things
            foreach(int item in myList)
                total += item; // No need to unbox
        }
</pre>
<p>Generic are similar to templates in C++, they allow you to specify a type and the compiler will generate all the required code. In our example we specify that our list is of type int, so the compiler will create a List class that supports integers. There is no longer a need to convert our integer type to an object first.  If you would like to know more about how generics work have a look at another post I wrote on the subject: <a id="s6of" title="Generics in C#" href="../generics-in-c/">Generics in C#</a> .</p>
<h3>So how much of a difference does boxing make?</h3>
<p>Boxing is slower but how much is the difference and do you need to care? To put things into perspective I tested the timing on the three code examples above. For this I used .NET&#8217;s Stopwatch class to <a id="gx9k" title="measure our code's performance" href="../timing-function-performance-stopwatch-class/">measure the code&#8217;s performance</a>. First of all, the .NET runtime is pretty fast and I found that I needed to set the loop iterations at some 10 milion before I was able to get a consistent result across runs.</p>
<ul>
<li>Boxing/Unboxing ListArray example: 2580 ms</li>
<li>Boxing/Unboxing List&lt;object&gt; example: 2050ms</li>
<li>Non boxing List&lt;int&gt; example: 825 ms</li>
</ul>
<p>The non boxing List&lt;int&gt; example is about 2.5 times faster than List&lt;object&gt;, which is quite considerable.</p>
<h3>To finish up&#8230;</h3>
<p>Based on this should you rewrite all your code to implement generics? Probably not unless you have several tight loops that could use your attention, note that this only applies to value types (structs, ints) . For reference types (i.e. all classes) this is less of a problem as they are stored as a reference anyway. </p>
<p>It is however a good idea to implement generics in any code you write from here on. Not just because of the potential gains in speed but also because generics provide the compiler with much more information.</p>
<ul>
<li>Generics reduce the number of coding errors as you have compile-time checking of types</li>
<li>Generics are more readable, you don&#8217;t need to cast all over the place and it&#8217;s always obvious what type it is associated with</li>
</ul>
<p>Also if possible avoid passing value types as parameters to methods if these force a conversion to an object.</p>
<p>Image credit: Wall of boxed by <a rel="nofollow" href="http://www.flickr.com/photos/celesteh/">celesteh</a></p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.dijksterhuis.org%2fexploring-boxing%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.dijksterhuis.org%2fexploring-boxing%2f" border="0" alt="kick it on DotNetKicks.com" /></a></p>
<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dijksterhuis.org/exploring-boxing/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Exploring C# reflection</title>
		<link>http://www.dijksterhuis.org/exploring-reflection/</link>
		<comments>http://www.dijksterhuis.org/exploring-reflection/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 16:00:39 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Chapter]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[reflection]]></category>

		<guid isPermaLink="false">http://www.dijksterhuis.org/?p=680</guid>
		<description><![CDATA[In this post I look at how we can simply retrieve basic information about our own types, discover their methods and lastly how we can import a foreign assembly, inspect its contents, load a class and execute its methods. When C# compiles your code it not only stores the program in the assembly but the [...]<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.dijksterhuis.org/wp-content/uploads/2009/02/horses.jpg" alt="Reflecting on our C# selves" title="Reflecting on our C# selves" width="500" height="260" class="alignnone size-full wp-image-684" /></p>
<p><em>In this post I look at how we can simply retrieve basic information about our own types, discover their methods and lastly how we can import a foreign assembly, inspect its contents, load a class and execute its methods. </p>
<p>When C# compiles your code it not only stores the program in the assembly but the complete information on each of the structures you have defined. Each class, its types, parameters and methods described into detail are all available. This might sound like stating the obvious, but until recently most compilers treated this kind of &#8220;meta&#8221; data as a waste of space and never included it into the final assembly.</em></p>
<p><span id="more-680"></span></p>
<p>Through reflection C#  offers a way of inspecting this meta information from a running program. The program reflects on itself to discover itself. It can use this to change the way it runs, or to report the results back to the user.</p>
<p>Why is this useful? If you distribute an application that accepts third plug-ins you need some kind of mechanism to inspect whether the supplied plug-in provides the correct set of methods for your code to work with. Very similar to how Visual Studio works with plug-ins.</p>
<p><strong>Type</strong></p>
<p>To be able to interact with their own code C# programs rely heavily on the <em>Type</em> class. The <em>Type</em> class can represent all C# type declarations: class types, interface types, array types, value types, enumeration types, type parameters etc. You can use it to query a type and discover what kind of contents it has.</p>
<p><em>GetType()</em> is the most common way to access C# reflection and I&#8217;ll show in the next example how you can find out the original type of an object after it has been cast down to a basic object. The<em> GetType()</em> method is inherited from object, so each C# object has access to it. As can be expected, <em>GetType()</em> returns an instance of the Type class.</p>
<p>But first have a look a simple example of how we can use <em>GetType()</em></p>
<pre class="brush: c#">
    using System;
    using System.Reflection;
    class MainClass
    {
        // This routine takes an object, which is the root of all
        // types in C#
        public static void PrintType(object Data)
        {
            Console.WriteLine(&quot;Type of Data: {0}&quot;,Data.GetType());
        }

        public static void Main(string[] args)
        {
            string msg = &quot;Hello World&quot;;
            PrintType(msg);
            int    theValue = 1024;
            PrintType(theValue);
        }
    }
</pre>
<p>This will print:</p>
<blockquote><p>Type of Data: System.String<br />
Type of Data: System.Int32
</p></blockquote>
<p>If you know that the object you were passed was really a <em>System.Int32</em> object, you can could cast it back and modify it as a regular integer. The following works but isn&#8217;t very nice:</p>
<pre class="brush: c#">
         object Test = new int();

         // This only works if the above object is an integer
         if (Test.GetType().ToString()==&quot;System.Int32&quot;)
            {
                int MyInt = (System.Int32) Test;
                MyInt = 20;
            }
</pre>
<p>A much better way of course in your own code to do the following:</p>
<pre class="brush: c#">
         object Test = new int();
         if (Test is int)
            {
                int MyInt = (int) Test;
                MyInt = 20;
            }
</pre>
<p><strong>The TypeOf operator</strong></p>
<p>The <em>typeof()</em> operator works in similar fashion at GetType but on type definitions at compile time. The <em>GetType()</em> operator works on instances of variables and is available at run-time. The benefit is that you don&#8217;t have to instantiate a class to obtain an type instance. To illustrate the difference have a look at the following:</p>
<pre class="brush: c#">
Type e = typeof(MyExampleClass);

// This is the same as:

MyClass example = new MyExampleClass();
Type t = example.GetType();
</pre>
<p><strong>Using Type to query a class methods and members</strong></p>
<p>Of course we can obtain much more information about a class than just its name. We can use the <em>GetMethods()</em> method to obtain a list of all the methods in the class, and <em>GetMembers()</em> to obtain all its member variables. Not only that, we can also call these members after we discover them.</p>
<pre class="brush: c#">
using System;
using System.Reflection;

namespace Reflection
{
    class MySecretClass
    {
        public int Z;

        public int Add(int x) { return x+1; }
        public int Sub(int x) { return x-1; }

         MySecretClass()
        {
            Z = 0;
        }
    }

    class MainClass
    {
        public static void Main(string[] args)
        {
         Type t = typeof(MySecretClass);

         MethodInfo[] MethodArray = t.GetMethods();
         foreach (MethodInfo Method in MethodArray)
          Console.WriteLine(&quot;Method: {0}&quot;,Method.ToString());

         MemberInfo[] MemberArray = t.GetMembers();
         foreach (MemberInfo Member in MemberArray)
          Console.WriteLine(&quot;Member: {0}&quot;,Member.ToString());

        }
    }
}
</pre>
<p><strong>Loading an external assembly</strong></p>
<p>Inspecting our own types is not nearly as adventurous as trying to decode the definitions found in a assembly you are trying to understand or validate. The following code loads the &#8220;mscorlib.dll&#8221; (which is the present in all .NET environments) and prints its name, version, culture and public key:</p>
<pre class="brush: c#">
            System.Reflection.Assembly LoadedAssembly = System.Reflection.Assembly.Load(&quot;mscorlib.dll&quot;);
            System.Console.WriteLine(LoadedAssembly.GetName());
</pre>
<p>We can query the assembly for a couple of basic variables, such as its name, location etc:</p>
<pre class="brush: c#">
            Console.WriteLine(&quot;Full Name: {0}&quot;, LoadedAssembly.FullName);
            Console.WriteLine(&quot;Location: {0}&quot;, LoadedAssembly.Location);
            Console.WriteLine(&quot;Code Base: {0}&quot;, LoadedAssembly.CodeBase);
            Console.WriteLine(&quot;Escaped Code Base: {0}&quot;, LoadedAssembly.EscapedCodeBase);
            Console.WriteLine(&quot;Loaded from GAC: {0}&quot;, LoadedAssembly.GlobalAssemblyCache);
</pre>
<p>Now the assembly is in memory we can explore it using the above introduced Type class, the GetTypes() method returns an array of all types in the assembly. The full code that queries the mscorlib.dll in detail is below:</p>
<pre class="brush: c#">
using System;
using System.Reflection;

namespace Reflection
{
    class MainClass
    {

        public static void Main(string[] args)
        {
            System.Reflection.Assembly LoadedAssembly = System.Reflection.Assembly.Load(&quot;mscorlib.dll&quot;);
            System.Console.WriteLine(LoadedAssembly.GetName());

            Console.WriteLine(&quot;Full Name: {0}&quot;, LoadedAssembly.FullName);
            Console.WriteLine(&quot;Location: {0}&quot;, LoadedAssembly.Location);
            Console.WriteLine(&quot;Code Base: {0}&quot;, LoadedAssembly.CodeBase);
            Console.WriteLine(&quot;Escaped Code Base: {0}&quot;, LoadedAssembly.EscapedCodeBase);
            Console.WriteLine(&quot;Loaded from GAC: {0}&quot;, LoadedAssembly.GlobalAssemblyCache);

            Type[] types = LoadedAssembly.GetTypes();

            foreach (Type t in types)
            {
                Console.WriteLine (&quot;Name: {0}&quot;, t.FullName);
                Console.WriteLine (&quot;Namespace: {0}&quot;, t.Namespace);
            }
        }
    }
}
</pre>
<p><strong>Calling dynamically bound assemblies at runtime</strong></p>
<p>After we have loaded an assembly we want to execute some code in it. In the above example we used the <em>mscorelib.dll</em> because it conveniently is available on all .NET systems. In the following example I show how you can create an object instance and call a named method.</p>
<p>The <em>System.DateTime</em> class is one of many stored in this dll, and we are interested in the <em>ToLongDateString</em> method. Normally we would call it in a manner similar to the below:</p>
<pre class="brush: c#">
System.DateTime myTime   = new System.DateTime(2000,1,1,12,0,0);
Console.WriteLine(&quot;Current Time: {0}&quot;,myTime.ToLongDateString());
</pre>
<p>As we have loaded <em>mscorlib</em> dynamically we need to go through some more steps to locate the method and constructor we are interested in:</p>
<pre class="brush: c#">
object myObject = LoadedAssembly.CreateInstance(&quot;System.DateTime&quot;,false,BindingFlags.ExactBinding,null,new Object[] {2000,1,1,12,0,0},null,null);
</pre>
<p>We use <em>CreateInstance</em> to create an instance of the class we require, &#8220;System.DateTime&#8221;. Just ignore the other parameters for now; the second important one is where we pass an object array containing the exact number of variables to match the correct constructor.</p>
<p>Next we need to obtain a handle to the method inside the class we want to invoke.</p>
<pre class="brush: c#">
MethodInfo m = LoadedAssembly.GetType(&quot;System.DateTime&quot;).GetMethod(&quot;ToLongDateString&quot;);
</pre>
<p>We execute the method by calling &#8220;Invoke&#8221;, passing our object and an object array of parameters (null as ToLongDateString does not take any). We need to cast the resulting object to a string.</p>
<pre class="brush: c#">string result = (string) m.Invoke(myObject,null);
Console.WriteLine(&quot;The time and date: {0}&quot;,result);
</pre>
<p>From the above it is clear that calling methods from a dynamically loaded and bound assembly is considerably more work. It does however allow you to extend your program through third party extensions, or by enabling functionality through assemblies that might not be available on all systems.</p>
<p>The full code for the final example is below:</p>
<pre class="brush: c#">
using System;
using System.Reflection;

namespace Reflection
{
        class MainClass
        {

                public static void Main(string[] args)
                {
                        System.Reflection.Assembly LoadedAssembly = System.Reflection.Assembly.Load(&quot;mscorlib.dll&quot;);
                        System.Console.WriteLine(LoadedAssembly.GetName());

                        // Doing it the statically bound way
                        System.DateTime myTime   = new System.DateTime(2000,1,1,12,0,0);
                        Console.WriteLine(&quot;Current Time: {0}&quot;,myTime.ToLongDateString());

                        // And now through an assembly loaded at runtime
                        object myObject = LoadedAssembly.CreateInstance(&quot;System.DateTime&quot;,false,BindingFlags.ExactBinding,null,new Object[] {2000,1,1,12,0,0},null,null);

                        MethodInfo m = LoadedAssembly.GetType(&quot;System.DateTime&quot;).GetMethod(&quot;ToLongDateString&quot;);
                        string result = (string) m.Invoke(myObject,null);
                        Console.WriteLine(&quot;The time and date: {0}&quot;,result);

                }
        }
}
</pre>
<p>Image credit: <a rel="nofollow" href="http://www.flickr.com/photos/mikebaird/">Mike Baird</a></p>
<p>This is a post from <a href="http://www.dijksterhuis.org">Martijn's C# Coding Blog</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.dijksterhuis.org/exploring-reflection/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

