1

I decided to add custom Get/SetValue(with INotifyPropertyChanged) helper functions in my ViewModelBaseClass similar to the type safe method mentioned here. But I want to add optional initializer to the Get helper Function which has sane defaults. Unfortunately the default keyword initializes reference types to null, nullable value types to null, and value types to default values.

I want to make a generic function that would be called by the Get helper that returns default values for types, default values values for BaseType for Nullable(if possible), and default constructors for reference types that have default constructors. For reference types that don't implement the constructor I guess it could return null. But figuring out how to call new T() vs default(T) in an if else is difficult, the compiler says it doesn't have the right constraints(because of course constrains are checked at runtime).

As an alternative I suppose I could use Jon Skeet's http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx on the Get helper method( of which he said:

This is possibly the most horrible code I've ever written.

Please, please don't use it in real life. Use different method names or something like that. Still, it's a fun little puzzle, isn't it?

) as a benefit it would might allow me to force reference types without default constructors to specify a non optional init Func.

Community
  • 1
  • 1
Roman A. Taycher
  • 18,619
  • 19
  • 86
  • 141

1 Answers1

1

You could try this method. I couldn't seem to figure out a better way to return a default value for the underlying type of a nullable type. I'll keep searching and update my post if I find something. However, you can't pass reference types without a parameterless constructor.

static T GetDefault<T>() where T : new()
{
    var type = typeof (T);
    var underlying = Nullable.GetUnderlyingType(type);
    if (underlying != null)
        return (T) Activator.CreateInstance(underlying);
    return new T();
}

Alternatively, you can use this version without the new() contraint which uses Reflection in all cases and is, for that reason, slower.

static T GetDefault<T>()
{
    var type = typeof (T);
    var underlying = Nullable.GetUnderlyingType(type);
    if (underlying != null)
        return (T) Activator.CreateInstance(underlying);
    var constructor = type.GetConstructor(Type.EmptyTypes);
    return (T) (constructor == null ? default(T) : Activator.CreateInstance(type));
}
e_ne
  • 8,340
  • 32
  • 43