Gut zu Wissen « Bernhard Krenz

Gut zu Wissen

Instanz aus Klassennamen erzeugen

Nehmen wir folgenden Fall an: Der Name einer Klasse liegt als string vor und es gilt eine Instanz der Klasse zu erzeugen.

Das kann zum Beispiel so funktionieren:

// you got the name of the class from somewhere
string className = "Message";
// create the type of the class using the destinated namespace
var type = Type.GetType("ValueObjects." + className, false); 
// create the instance now
var message = Activator.CreateInstance(type) as Message;

In ASP.Net funktioniert das allerdings nicht. Hier ist ein Workarund über den BuildManager (using System.Web.Compilation) notwendig:

// you got the name of the class from somewhere
string className = "Message";
// create the type of the class using the destinated namespace
var type = BuildManager.GetType("ValueObjects." + className, false);
// create the instance now
var message = Activator.CreateInstance(type) as Message;

Existiert eine Konstante?

Wer regelmäßig mit iOS arbeitet wird schnell einmal mit dem Problem konfrontiert, dass eine zu verwendende System-Konstante nur in einer neueren iOS-Version verfügbar ist.

Hier stellt sich die Frage, wie zu prüfen ist, ob die Konstante in der iOS-Version des Nutzers überhaupt zur Verfügung steht, um durch eine geeignete Weiche Abstürze zu vermeiden.

Das Ganze zeige ich am Beispiel einer Observer-Konstante des MPMoviePlayerControllers zum Abspielen von Videos, welche einem die Möglichkeit bietet, ein Video erst dann einzublenden, wenn das erste Frame zur Verfügung steht. Denn nur so kann man ein Flickern am Anfang des Videos vermeiden:

if (&MPMoviePlayerReadyForDisplayDidChangeNotification != NULL) // check if constant exists
{
	// >= iOS 6.0, use readyForDisplay property
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoIsVisibleChanged:) name:MPMoviePlayerReadyForDisplayDidChangeNotification object:nil];
}
else
{
	// < iOS 6.0, use playbackState property
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
}

SortedDictionary und ArgumentException

Neulich hatte ich einen sehr merkwürdigen Fehler bei der Verwendung eines SortedDictionary<string, string>. Ich erhielt eine ArgumentException mit der Beschreibung „Ein Eintrag mit dem gleichen Schlüssel ist bereits vorhanden.“

Das Ganze war umso verwunderlicher, da die Daten 1:1 aus einem normalen Dictionary<string, string> übernommen wurden und demzufolge der Fehler schon an dieser Stelle hätte auftreten müssen.

Um auf die Ursache des Fehlers zu kommen, habe ich folgende Testklasse geschrieben:

public class Sorter : IComparer
{
	public Sorter()
	{
		var sortedDictionary = new SortedDictionary<string, string>(this);
		sortedDictionary.Add("test", "Hallo Welt");
		sortedDictionary.Add("Test", "Hallo zurück");
	}

	public int Compare(string x, string y)
	{
		x = x.ToLower();
		y = y.ToLower();

		return x.CompareTo(y);
	}
}

Mach beachte die Zeile 12 und 13. Die Sortierung sollte case-insensitive erfolgen. Dies hat aber zur Folge, dass nicht der Angegebene Schlüssel „Test“ eingefügt, sondern der aus dem Vergleich, nämlich „test“. Ohne diese Zeilen würden der Fehler nicht auftreten.

Für mich ist dieses Verhalten nicht ganz nachvollziehbar und es fühlt sich ganz leicht nach einem Bug an. Denn obwohl die Vergleichsmethode den Wert „0“ für „gleich“ zurück gibt, sollte dennoch der ursprünglich angegebene Schlüssel verwendet werden.


Copyright © 2012-2024 Bernhard Krenz Alle Rechte vorbehalten.