Tag Archives: C#

Quick reminder about the workings of Type.IsAssignableFrom

Here is a quick reminder about the workings of Type.IsAssignableFrom:

class Fruit {}
class Banana : Fruit {}

[Test]
public void CanAssignBananaToFruit()
{
 var fruit = typeof (Fruit);
 var banana = typeof (Banana);
 Assert.IsTrue(fruit.IsAssignableFrom(banana));
}

[Test]
public void CanNotAssignFruitToBanana()
{
 var fruit = typeof(Fruit);
 var banana = typeof(Banana);
 Assert.IsFalse(banana.IsAssignableFrom(fruit));
}

I really hate this API because it always seems backward to me. Here is how i really want to use it:

Assert.IsTrue(banana.CanBeAssignedTo(fruit));
Assert.IsFalse(fruit.CanBeAssignedTo(banana));

With the aid of an extension method we can easily achieve this:

public static bool CanBeAssignedTo(this Type sourceType, Type destinationType)
{
 return destinationType.IsAssignableFrom(sourceType);
}

Removing Dead Tracks (Duplicates that don't exist) from iTunes using C#

Last week i noticed the following post from Scott Hanselman: Removing Dead Tracks (Duplicates that don’t exist) from iTunes using C#. As a good boy scout i noticed that these days iTunesLib.IITTrackCollection inherits from IEnumerable so i rewrote the code a little:

class Program
{
 [STAThread]
 static void Main()
 {
  var itunes = new iTunesApp();
  itunes.DeleteTracksThatDoNotExist();
 }
}

public static class ITunesExtensions
{
 public static void DeleteTracksThatDoNotExist(this IiTunes itunes)
 {
  var tracksThatDoNotExist = FindTracksThatDoNotExist(itunes);
  foreach (var track in tracksThatDoNotExist) track.Delete();
 }

 public static IEnumerable<iitfileOrCDTrack> FindTracksThatDoNotExist(this IiTunes iTunes)
 {
  return iTunes.LibraryPlaylist.Tracks
   .OfType<iitfileOrCDTrack>()
   .Where(track => !File.Exists(track.Location));
 }
}

Sometimes you can write it better than Resharper

Here is a real-life example of when people are much better expressing intent than a tool: Consider the following code from a typical Silverlight Navigation application:

foreach (UIElement child in LinksStackPanel.Children)
{
 var hb = child as HyperlinkButton;
 if (hb != null && hb.NavigateUri != null)
 { .. }
}

Resharper proposed to write this as following:

foreach (var hb in LinksStackPanel.Children
 .Select(child => child as HyperlinkButton)
 .Where(hb => hb != null && hb.NavigateUri != null))
{ .. }

Here is what i wrote instead:

foreach (var hb in LinksStackPanel.Children
 .OfType<hyperlinkButton>()
 .Where(hb => hb.NavigateUri != null))
{ .. }

WCF REST: generate correct Content-Length header for HEAD request

The point of a HEAD request is to return a Content-Length header, but with an empty body. The WCF transport stack has the annoying ‘feature’ that it ‘corrects’ the Content-Length header based on the stream that is returned. With the aid of Carlos Figueira’s MyLengthOnlyStream i was able to workaround that ‘feature’ :) (I know, i know, a good old HttpHandler is so much easier to implement!)

Support both GET and HEAD requests on the same method with WCF REST

A while ago i had to modify an existing WCF REST service which was being consumed by BITS. Apparently the implementation has changed in Windows7 in such a way that the BITS client first makes a HEAD request to discover the file size.

The following attempts did not work:

// A method can not have both WebGet and WebInvoke attributes
[OperationContract]
[WebGet]
[WebInvoke(Method="HEAD")]
public Stream Download(string token) { }


// A method can not have multiple WebInvoke attributes
[OperationContract]
[WebInvoke(Method="GET")]
[WebInvoke("HEAD")]
public Stream Download(string token) { }

The trick is to use * as Method and handle the method related logic in your code:

[OperationContract]
[WebInvoke(Method="*")]
public Stream Download(string token)
{
 var method = WebOperationContext.Current.IncomingRequest.Method;
 if (method == "HEAD") return ProcessHead();
 if (method == "GET") return ProcessGet();
 throw new ArgumentException(method + " is not supported.");
}

Enumerating SpecialFolders

Environment.SpecialFolder is a value-type that i always seem to forget about. Let’s try to do something about that by posting about it here ;)

foreach (var name in Enum.GetNames(typeof(Environment.SpecialFolder)))
{
 var specialFolder = (Environment.SpecialFolder)Enum.Parse(typeof(Environment.SpecialFolder), name);
 Console.WriteLine("{0,25} => {1}", name, Environment.GetFolderPath(specialFolder));
}


Desktop C:\Users\timvw\Desktop
Programs C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
Personal C:\Users\timvw\Documents
MyDocuments C:\Users\timvw\Documents
Favorites C:\Users\timvw\Favorites
Startup C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
Recent C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Recent
SendTo C:\Users\timvw\AppData\Roaming\Microsoft\Windows\SendTo
StartMenu C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Start Menu
MyMusic C:\Users\timvw\Music
DesktopDirectory C:\Users\timvw\Desktop
MyComputer
Templates C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Templates
ApplicationData C:\Users\timvw\AppData\Roaming
LocalApplicationData C:\Users\timvw\AppData\Local
InternetCache C:\Users\timvw\AppData\Local\Microsoft\Windows\Temporary Internet Files
Cookies C:\Users\timvw\AppData\Roaming\Microsoft\Windows\Cookies
History C:\Users\timvw\AppData\Local\Microsoft\Windows\History
CommonApplicationData C:\ProgramData
System C:\Windows\system32
ProgramFiles C:\Program Files
MyPictures C:\Users\timvw\Pictures
CommonProgramFiles C:\Program Files\Common Files

Get root directory for IsolatedStorageFiles

Sometimes you want to know the absolute path of a file that is persisted with IsolatedStorageFile. Apparently there is an internal property RootDirectory which contains this information:

public static class IsolatedStorageFileExtensions
{
 public static string GetRootDirectory(this IsolatedStorageFile isf)
 {
  var property = isf.GetType().GetProperty("RootDirectory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty);
  return (string)property.GetValue(isf, null);
 }
}

Here is a real world example of using SharpBITS.NET to download a file to IsolatedStorage:

class Program
{
 static void Main()
 {
  var mgr = new BitsManager();
  mgr.OnJobError += mgr_OnJobError;
  mgr.OnJobTransferred += mgr_OnJobTransferred;

  var job = mgr.CreateJob("job@" + DateTime.Now, JobType.Download);
  var src = @"http://localhost/";
  var dst = Path.Combine(GetIsfRoot(), "test.html");
  job.AddFile(src,dst);
  job.Resume();

  Console.WriteLine("running...");
  Console.ReadKey();
 }

 static void mgr_OnJobTransferred(object sender, NotificationEventArgs e)
 {
   e.Job.Complete();
   Console.WriteLine("completed: " + e.Job.DisplayName);
  }

 static void mgr_OnJobError(object sender, ErrorNotificationEventArgs e)
 {
  Console.WriteLine("error: " + e.Error.Description);
 }

 static string GetIsfRoot()
 {
  using (var f = IsolatedStorageFile.GetUserStoreForAssembly())
  {
   return f.GetRootDirectory();
  }
 }
}

Exploring System.Interactive

A couple of weeks ago i was working on an application that would transfer data through a couple of components as a List<object>. In essence, all we were doing over and over again was the following:

interface IMapper<tentity>
{
 TEntity FromObjectList(List<object> objectList);
 List<object> ToObjectList(TEntity entity);
}

My initial implementation (using EnumerableEx operators from Reactive Extensions) looked like this:

public TEntity FromObjectList(List<object> objectList)
{
 var entity = new TEntity();

 properties
  .Zip(objectList, (property, value) => AssignValueToProperty(entity, property, value))
  .Run();

 return entity;
}

int AssignValueToProperty(object entity, PropertyInfo property, object value)
{
 property.SetValue(entity, value, null);
 return 0;
}

public List<object> ToObjectList(TEntity entity)
{
 return properties
  .Select(property => property.GetValue(entity, null))
  .ToList();
 }

And the consumer code looks like this:

var person = new Person {  Id = 2, Score = 1.3, Name = "Tim", Title = "Sir" };

var personMapper = new Mapper<person>()
 .Map(x => x.Id)
 .Map(x => x.Score)
 .Map(x => x.Name)
 .Map(x => x.Title);

var data = personMapper.ToObjectList(person);
var clonedPerson = personMapper.FromObjectList(data);

Wait a minute, in most situations we simply want to map all properties on the object. Let’s create a mapper for this:

class AutoMapper<tentity> : Mapper<tentity> where TEntity : new()
{
 public AutoMapper()
 {
  typeof(TEntity).GetProperties().Run(property => Map(property));
 }
}

And now we don’t have to waste time doing the same thing over and over again! Because we always need to map all properties of our types we ended up with the following:

public static class Mapper
{
 public static List<object> ToObjectsList<tentity>(this TEntity entity)
 {
  return entity.GetType().GetProperties()
   .Select(property => property.GetValue(entity, null))
   .ToList();
  }

 public static TEntity ToEntity<tentity>(this List<object> objectsList) where TEntity : new()
 {
  TEntity entity = new TEntity();
  entity.GetType().GetProperties()
   .Zip(objectsList, (property, value) =>{ property.SetValue(entity, value,null); return 0;})
   .Run();
  return entity;
 }
}

Learned something from Resharper: Enumerable.OfType<TResult>

A couple of weeks ago i discovered Enumerable.OfType<TResult> when i let Resharper rewrite my code as a Linq statement. Here is the original code:

var selectedPersons = new List<personSelectItem>();
foreach(var selectedItem in selectedItems)
{
 var selectedPerson = selectedItem as PersonSelectItem;
 if (selectedPerson == null) continue;
 selectedPersons.Add(selectedPerson);
}

And here is how it looks after the rewrite:

var selectedPersons = selectedItems.OfType<personSelectItem>().ToList();

Yup, the Resharper license was definitely worth it’s money.

Calculate EndpointAddress for Silverlight client

Because Silverlight checks the origin it considers http://localhost and http://127.0.0.1 as different locations. In case you want your visitors to be able to use both addresses you can recalculate the address as following:

EndpointAddress GetEndpointAddress(EndpointAddress endpointAddress)
{
 var scheme = Application.Current.Host.Source.GetComponents(UriComponents.Scheme, UriFormat.Unescaped);
 var serverAndPort = Application.Current.Host.Source.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped);
 var pathAndQuery = endpointAddress.Uri.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
 return new EndpointAddress(scheme + "://" + serverAndPort + pathAndQuery);
}

And you can use this method as following:

var client = new DirectoryServiceClient();
client.Endpoint.Address = GetEndpointAddress(client.Endpoint.Address);
client.GetMessageCompleted += ClientGetMessageCompleted;
client.GetMessageAsync();