是否可以将空引用传递给Init视图模型?

时间:2017-05-24 14:59:08

标签: xamarin mvvmcross

我在一个视图模型上进行此调用

ShowViewModel<MyViewModel>(
    new MyParams { ... }
);

在MyViewModel上,我有一个完美的Init方法

public void Init(MyParams params)
{
    if (params != null)
    {
        // some logic
    }
    else 
    {
        // some other logic
    }
}

在另一个视图模型上我有

ShowViewModel<MyViewModel>();

我希望在MyViewModel init方法上收到null,而不是我得到一个&#39; MyParams&#39;的实例。因为我有特定的逻辑来处理没有参数的调用

,所以会产生问题

我有自定义的演示者逻辑可能对此负责,但乍一看我无法识别任何自定义逻辑负责。这是复杂参数的标准行为吗?

2 个答案:

答案 0 :(得分:1)

不幸的是,没有办法使用参数对象传递 null

原因是当Mvx创建ViewModel并尝试调用Init方法时,它会首先将您的对象实例转换为简单字典(键/值对)。如果使用no arg版本,则会创建一个空字典。此时,它会创建一个包含字典的MvxBundle

当Mvx最终准备好调用你的Init方法时,它会使用这个字典并尝试创建一个实际的对象。

这种方法可以创建要传递给Init的实例。

MvxSimplePropertyDictionaryExtensionMethods.Read()

https://github.com/MvvmCross/MvvmCross/blob/8a824c797747f74716fc64c2fd0e8765c29b16ab/MvvmCross/Core/Core/Platform/MvxSimplePropertyDictionaryExtensionMethods.cs#L54-L72

public static object Read(this IDictionary<string, string> data, Type type)
{
    var t = Activator.CreateInstance(type);
    var propertyList =
        type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy).Where(p => p.CanWrite);

    foreach (var propertyInfo in propertyList)
    {
        string textValue;
        if (!data.TryGetValue(propertyInfo.Name, out textValue))
            continue;

        var typedValue = MvxSingletonCache.Instance.Parser.ReadValue(textValue, propertyInfo.PropertyType,
                                                                     propertyInfo.Name);
        propertyInfo.SetValue(t, typedValue, new object[0]);
    }

    return t;
}

注意它如何调用Activator.CreateInstance(type),它总是会返回一个实例。

这就是为什么你永远不会在Init中获得 null 值。

我的建议是简单地向MyParams对象添加一个属性,并在你的无法arg版本中设置它。然后在Init中,您可以检查该属性以确定要执行的操作。

类似的东西:

ShowViewModel<MyViewModel>(new MyParams { HasNoParams = true });

public void Init(MyParams myParams)
{
    if (myParams.HasNoParams)
    {
        // do null flow here
    }
    else 
    {
        // do non-null flow here
    }
}

答案 1 :(得分:0)

你可以使用Dictionary&lt; TKEY的,TValue&GT;作为你的参数。