<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" version="2.0">
    <channel>
        <title>Tao Te Ka-Ching</title>
        <link>http://www.taotekaching.com/Default.aspx</link>
        <description>Working the cash register of the Great Tao</description>
        <language>en-US</language>
        <copyright>ZagNut</copyright>
        <generator>Subtext Version 2.5.1.19</generator>
        <image>
            <title>Tao Te Ka-Ching</title>
            <url>http://www.taotekaching.com/images/RSS2Image.gif</url>
            <link>http://www.taotekaching.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TaoTeKaChing" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="taotekaching" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/TaoTeKaChing" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FTaoTeKaChing" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
            <title>Dictionaries, Reflection, Private Fields, and Me...</title>
            <category>Programming</category>
            <link>http://www.taotekaching.com/archive/2011/09/30/Dictionaries-Reflection-Private-Fields-and-Me.aspx</link>
            <description>&lt;p&gt;Hello.&lt;/p&gt;  &lt;p&gt;So the other day at work I was confronted with a problem.  A particular class we use extensively throughout an enterprise solution was using OO to hide a &lt;font face="Courier New"&gt;Dictionary&amp;lt;string, object&amp;gt;&lt;/font&gt; from me...BUT ALL FOR NAUGHT!&lt;/p&gt;  &lt;p&gt;Said class has a private field which is basically a &lt;font face="Courier New"&gt;Dictionary&amp;lt;string, object&amp;gt;&lt;/font&gt; instance.  You could add to it just fine via a public method created for that very purpose.  But as is typical with any ongoing large project, we suddenly needed the ability to remove from that field by a given key just for unit testing, and the powers that be frowned heavily on adding a public remove method just for this purpose.  Time for reflection.&lt;/p&gt;  &lt;p&gt;Here’s a more generic example of what needed to be done.  Consider the following class:&lt;/p&gt;  &lt;pre&gt;    public class Test
    {
	public void Add(string s, object o)
	{
		_field.Add(s, o);
	}
        private Dictionary&amp;lt;string, object&amp;gt; _field = new Dictionary&amp;lt;string, object&amp;gt;()
        {
            { "One", 1 },
            { "Two", 2 }
        };
    }&lt;/pre&gt;

&lt;p&gt;On instantiating &lt;font face="Courier New"&gt;Test&lt;/font&gt;, we want to get rid of the &lt;font face="Courier New"&gt;{ "One", 1 }&lt;/font&gt; item from _field.  We would normally do this easily with the call:&lt;/p&gt;

&lt;pre&gt;_field.Remove("One");&lt;/pre&gt;

&lt;p&gt;But unfortunately, the &lt;font face="Courier New"&gt;Dictionary&lt;/font&gt; is hidden from us.  We can access it via reflection easily, though:&lt;/p&gt;

&lt;pre&gt;	Test a = new Test();
	Type TestType = a.GetType();
	FieldInfo ttField = TestType.GetField("_field",
		BindingFlags.NonPublic | BindingFlags.Instance);
	object v = ttField.GetValue(a);&lt;/pre&gt;

&lt;p&gt;Now that we have our &lt;font face="Courier New"&gt;_field&lt;/font&gt; ref’d by our &lt;font face="Courier New"&gt;object v&lt;/font&gt;, we can call it’s &lt;font face="Courier New"&gt;Remove&lt;/font&gt; function and have our gravy:&lt;/p&gt;

&lt;pre&gt;	MethodInfo ttFieldDictRemove = v.GetType().GetMethod("Remove");
	ttFieldDictRemove.Invoke(v, new object[] { "One" });&lt;/pre&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;None of this is necessarily rocket science, but there are two parts to this that can use a little more analysis: the need for the &lt;font face="Courier New"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx" target="_blank"&gt;BindingFlags.Instance&lt;/a&gt;&lt;/font&gt;, and that our &lt;font face="Courier New"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.getvalue.aspx" target="_blank"&gt;GetValue&lt;/a&gt;&lt;/font&gt; call returns a ref to &lt;font face="Courier New"&gt;_field&lt;/font&gt; and not a copy.&lt;/p&gt;

&lt;p&gt;The &lt;font face="Courier New"&gt;BindingFlags.Instance&lt;/font&gt; is required to “see” the member field &lt;font face="Courier New"&gt;_field&lt;/font&gt;.  At first we might simply assume that this is just referring to instance variables versus class variables.  Were &lt;font face="Courier New"&gt;_field&lt;/font&gt; declared &lt;font face="Courier New"&gt;static&lt;/font&gt; in &lt;font face="Courier New"&gt;Test&lt;/font&gt;, we could simply change &lt;font face="Courier New"&gt;BindingFlags.Instance&lt;/font&gt; to &lt;font face="Courier New"&gt;BindingFlags.Static&lt;/font&gt;, and we’d be “see”-ing &lt;font face="Courier New"&gt;_field&lt;/font&gt; again.&lt;/p&gt;

&lt;p&gt;However, if &lt;font face="Courier New"&gt;_field&lt;/font&gt; is not &lt;font face="Courier New"&gt;static&lt;/font&gt; and &lt;font face="Courier New"&gt;public&lt;/font&gt;, suddenly we &lt;strong&gt;&lt;em&gt;can’t&lt;/em&gt;&lt;/strong&gt; have either &lt;font face="Courier New"&gt;BindingFlags&lt;/font&gt;.  &lt;font face="Courier New"&gt;NonPublic&lt;/font&gt; is understandable, but why not &lt;font face="Courier New"&gt;Instance&lt;/font&gt;?  Isn’t &lt;font face="Courier New"&gt;_field&lt;/font&gt; still an instance variable, just &lt;font face="Courier New"&gt;public&lt;/font&gt;?  How are accessors involved here?&lt;/p&gt;

&lt;p&gt;Really this is just something that can be misleading in the MSDN documentation.  For example, as of today, &lt;font face="Courier New"&gt;BindingFlags.Instance&lt;/font&gt; is described in the online docs for &lt;font face="Courier New"&gt;BindingFlags&lt;/font&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font face="Arial"&gt;&lt;em&gt;Instance  -  Specifies that instance members are to be included in the search.&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;BindingFlags&lt;/font&gt; is not so much a search as a filter (as specified on, say, the &lt;font face="Courier New"&gt;GetField&lt;/font&gt; page).  If we use &lt;font face="Courier New"&gt;BindingFlags.Public | BindingFlags.Instance&lt;/font&gt;, we’ll then “see” &lt;font face="Courier New"&gt;_field&lt;/font&gt;.  With no &lt;font face="Courier New"&gt;BindingFlags&lt;/font&gt; specified, we’ll “see” both instance and class variables that are &lt;font face="Courier New"&gt;public&lt;/font&gt;.  Interestingly, &lt;font face="Courier New"&gt;BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static&lt;/font&gt; should return the same as this but doesn’t, even though &lt;font face="Courier New"&gt;BindingFlags&lt;/font&gt; is a filter.&lt;/p&gt;

&lt;p&gt;Now regarding &lt;font face="Courier New"&gt;GetValue&lt;/font&gt;.  That &lt;font face="Courier New"&gt;GetValue&lt;/font&gt; returns a ref to &lt;font face="Courier New"&gt;_field&lt;/font&gt; is obvious when we run our code.  &lt;font face="Courier New"&gt;Remove&lt;/font&gt;-ing key &lt;font face="Courier New"&gt;"One"&lt;/font&gt; from &lt;font face="Courier New"&gt;object v&lt;/font&gt; will result in our instance &lt;font face="Courier New"&gt;a&lt;/font&gt; of &lt;font face="Courier New"&gt;Test&lt;/font&gt; no longer having &lt;font face="Courier New"&gt;"One"&lt;/font&gt; in it’s &lt;font face="Courier New"&gt;Dictionary&lt;/font&gt;.  Looking at it, however, it just &lt;em&gt;seems&lt;/em&gt; it should end up being only a copy, as the code reads something like “Based on what type class &lt;font face="Courier New"&gt;Test&lt;/font&gt; is, we know there’s a private field named &lt;font face="Courier New"&gt;_field&lt;/font&gt;, &lt;u&gt;so get it’s value&lt;/u&gt; and call that value’s method &lt;font face="Courier New"&gt;Remove&lt;/font&gt;”.  The underlined “so get it’s value” implies that we’re just getting whatever value that field currently has and not the actual field.  Since &lt;font face="Courier New"&gt;_field&lt;/font&gt; is a non-primitive (e.g. &lt;font face="Courier New"&gt;Dictionary&amp;lt;,&amp;gt;&lt;/font&gt;), we can assume that getting &lt;font face="Courier New"&gt;_field&lt;/font&gt;’s value implies the &lt;font face="Courier New"&gt;new Dictionary&amp;lt;,&amp;gt;&lt;/font&gt; we’d created in the heap.  With this is mind, &lt;font face="Courier New"&gt;GetValue&lt;/font&gt; should not work on a primitive type.  We’ll try the following:&lt;/p&gt;

&lt;pre&gt;    struct S
    {
        public int i;
        public void MinusOne()
        {
            i--;
        }
    }
    class Test
    {
        private S s = new S() { i = 3 };
    }
    class Program
    {
        static void Main(string[] args)
        {
            Test a = new Test();
            Type TestType = a.GetType();
            FieldInfo ttField = TestType.GetField("s", BindingFlags.NonPublic | BindingFlags.Instance);
            object v = ttField.GetValue(a);
            MethodInfo ttFieldStructChange = v.GetType().GetMethod("MinusOne");
            ttFieldStructChange.Invoke(v, new object[] { });
        }
    }&lt;/pre&gt;

&lt;p&gt;Sure enough, &lt;font face="Courier New"&gt;s.i&lt;/font&gt; remains 3 after the operation, ergo the need for &lt;font face="Courier New"&gt;GetValue&lt;/font&gt;’s counterpart &lt;font face="Courier New"&gt;SetValue&lt;/font&gt;.&lt;/p&gt;

&lt;p&gt;I’d love to pour through &lt;a href="http://www.amazon.com/CLR-via-C-Jeffrey-Richter/dp/0735627045/ref=ntt_at_ep_dpt_1" target="_blank"&gt;CLR via C#&lt;/a&gt; to make sure I haven’t misled anyone on some internals discoveries here, but in the meantime, if you have anything to add to this piece, please provide your insights in your comments and I’ll update the post.&lt;/p&gt;

&lt;p&gt;~zagnut&lt;/p&gt;
&lt;div style="display:none;"&gt;&lt;a href="http://www.taotekaching.com/search.aspx?q=dictionary" rel="tag"&gt;dictionary&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=reflection" rel="tag"&gt;reflection&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=field" rel="tag"&gt;field&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=oo" rel="tag"&gt;oo&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=remove" rel="tag"&gt;remove&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=fieldinfo" rel="tag"&gt;fieldinfo&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=getfield" rel="tag"&gt;getfield&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=bindingflags" rel="tag"&gt;bindingflags&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=nonpublic" rel="tag"&gt;nonpublic&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=instance" rel="tag"&gt;instance&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=getvalue" rel="tag"&gt;getvalue&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=methodinfo" rel="tag"&gt;methodinfo&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=getmethod" rel="tag"&gt;getmethod&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=invoke" rel="tag"&gt;invoke&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=clr" rel="tag"&gt;clr&lt;/a&gt;,&lt;a href="http://www.taotekaching.com/search.aspx?q=clr%20via%20c#" rel="tag"&gt;clr%20via%20c#&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.taotekaching.com/aggbug/97.aspx" width="1" height="1" /&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mT2TnyN2VqqS2jjawIHmZtOAv6w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mT2TnyN2VqqS2jjawIHmZtOAv6w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mT2TnyN2VqqS2jjawIHmZtOAv6w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mT2TnyN2VqqS2jjawIHmZtOAv6w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</description>
            <dc:creator>ZagNut</dc:creator>
            <guid>http://www.taotekaching.com/archive/2011/09/30/Dictionaries-Reflection-Private-Fields-and-Me.aspx</guid>
            <pubDate>Sat, 01 Oct 2011 02:36:39 GMT</pubDate>
            <comments>http://www.taotekaching.com/archive/2011/09/30/Dictionaries-Reflection-Private-Fields-and-Me.aspx#feedback</comments>
            <wfw:commentRss>http://www.taotekaching.com/comments/commentRss/97.aspx</wfw:commentRss>
            <trackback:ping>http://www.taotekaching.com/services/trackbacks/97.aspx</trackback:ping>
        </item>
    </channel>
</rss>

