Feedback

C# - Automatisch einen Nullable<T> Wert erzeugen

Veröffentlicht von am 9/24/2012
(0 Bewertungen)
Legt einer Instanz automatisch einen passenden Wert fest. Voraussetzung ist, dass das Argument "value" ein kompatibler Typ ist.
/* Verwendungsbeispiel
public class OBJ
{
   public string Text { get; set; }
   public Guid? Guid { get; set; }
}

   // Instanz
   var temp = new obj();

foreach(var prop in typeof(OBJ).GetProperties())
{
   object newValue = null;
   bool found = true;

   // Welche Property?
   switch(prop.Name)
   {
       case "Text":   // Neuer Wert
           newValue = "HELLO WORLD";
       break;

       case "Guid":
           newValue = Guid.NewGuid();
       break;

       default:
           found = false;
       break;
   }

   if(found){
   // Setzen
   prop.SetValueNullableCorrected(temp, newValue);
   }
}
*/

public static class Extension
/// <summary>
/// Legt den Instanzwert für die angegebene Property fest und passt die Werte (auch DBNull) auf den Typ der Property an (auch Nullable).
/// </summary>
/// <typeparam name="T">Die Zielinstanz der Property</typeparam>
/// <param name="info">Zielproperty in der Instanz</param>
/// <param name="instance">Zielinstanz</param>
/// <param name="value">Einzugebener Wert</param>
internal static void SetValueNullableCorrected<T>(this PropertyInfo info, T instance, object value)
{
	// ggf. Instanz erstellen
	if (instance == null) 
		instance = Activator.CreateInstance<T>();

	// Typ der Property
	var type = info.PropertyType;

	// Nullable<Typ>?
	if (type.IsGenericType)
	{
		if (type != value.GetType())
		{
			if (value == null || value == DBNull.Value)
			{
				info.SetValue(instance, null, null);
			}
			// Nullable<Typ> erzeugen und Wert eingeben
			else
			{
				NullableConverter nC = new NullableConverter(info.PropertyType);
				info.SetValue(instance, nC.ConvertFrom(value), null);
			}
		}
		else
		{
			// Wenn DBNull dann default(type)
			info.SetValue(instance, value == DBNull.Value ? Activator.CreateInstance(type) : value, null);
		}
	}
	// Normale Typen?
	else
	{
		if (value == DBNull.Value)
		{
			if (value.GetType().IsNullable())
			{
				info.SetValue(instance, null, null);
			}
			else
			{
				info.SetValue(instance, Activator.CreateInstance(type), null);
			}
		}
		else
		{
			var val = Convert.ChangeType(value, type);
			info.SetValue(instance, val, null);
		}
	}
}

/// <summary>
/// Prüft, ob ein Typ (null)-Werte annehmen kann oder nicht
/// </summary>
/// <param name="value">Typ, der geprüft werden soll</param>
/// <returns>Kann (null)-Werte annehmen (true) oder nicht (false)</returns>
internal static bool IsNullable(this Type realType)
{
	if (!realType.IsValueType)
	{
		// kein Wertetyp, daher kann der Typ (null)-Werte annehmen
		return true;
	}

	// Wenn Nullable.GetUnderlyingType() einen übergeordneten Typ ermitteln kann,
	// bedeutet dies, dass dies ein Wertetyp ist, der (null)-Werte annehmen kann,
	// z.B. bool?
	return Nullable.GetUnderlyingType(realType) == realType;
}

}
Abgelegt unter Nullable, T, C#.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!