Looking around for reasons why to use a static factory method like NewInstance instead of a constructor which takes arguments and ran into this answer Best practice for instantiating a new Android Fragment (which I don't really find compelling, but that's another story).
When I'm looking at the Xamarin Developer's guide, they have code which uses the factory, but then sets the local property directly without using a bundle or anything.
public class DatePickerFragment : DialogFragment,
DatePickerDialog.IOnDateSetListener
{
// TAG can be any string of your choice.
public static readonly string TAG = "X:" + typeof (DatePickerFragment).Name.ToUpper();
// Initialize this value to prevent NullReferenceExceptions.
Action<DateTime> _dateSelectedHandler = delegate { };
public static DatePickerFragment NewInstance(Action<DateTime> onDateSelected)
{
DatePickerFragment frag = new DatePickerFragment();
// WHY IS THIS ANY DIFFERENT FROM SETTING ANY OTHER VALUE DIRECTLY?
frag._dateSelectedHandler = onDateSelected;
// If this next line is bad, why is the above not also bad?
// frag.myIntValue = 5;
return frag;
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
DateTime currently = DateTime.Now;
DatePickerDialog dialog = new DatePickerDialog(Activity,
this,
currently.Year,
currently.Month,
currently.Day);
return dialog;
}
public void OnDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
{
// Note: monthOfYear is a value between 0 and 11, not 1 and 12!
DateTime selectedDate = new DateTime(year, monthOfYear + 1, dayOfMonth);
Log.Debug(TAG, selectedDate.ToLongDateString());
// HOW COME WE CAN USE THIS DIRECTLY WITHOUT A BUNDLE?
_dateSelectedHandler(selectedDate);
}
}
From my understanding (which is limited), setting variables directly has the chance of the fragment being destroyed and recreated and the values being lost.
The recommendation I've seen is to use the Bundle and call setArguments / getArguments to ensure the values are not lost.
Maybe this is because it is an Action? Are there other types which are safe to directly set on a fragment like this? Is the sample code actually doing something which is unsafe? Is there a better / more appropriate / consistent way? Is that why they initialize the field it to prevent NullReferenceException? Even if it is, doesn't that mean that this fragment will no longer work correctly if destroyed and recreated?