The simplest method would be to use reflection to get access to this internal constructor:
internal Song(string name, string filename, int duration);
Here is some code that does just that:
var ctor = typeof(Song).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null,
new[] { typeof(string), typeof(string), typeof(int) }, null);
song = (Song)ctor.Invoke(new object[] { "name", @"C:My MusicBlah.mp3", 0 });
Obviously this is not really ideal. I do not think the XNA runtime does minor-version updates (meaning that if your game uses XNA 4.0, it is always the same runtime), but I do not know for sure. By using an internal constructor your game is entirely at the mercy of binary updates by Microsoft. You probably want a nice big exception handler on that.
Additionally, I found that some MP3 files would (literally) silently fail to play. Also the Duration
property is obviously not filled in by this method.
(Obviously this is Windows-only code. But you can't really access random bits of the filesystem like this on WP7 or Xbox anyway.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…