是否可以删除此方法的通用参数?

时间:2018-11-30 14:58:42

标签: c# generics

我正在尝试为我的ViewModels创建一个导航服务-它只有一个问题。我希望我只是在这里错过了一些事情/做错了什么,因为否则我想我将不得不等待concepts被引入C#。

我的愿望是 转动这个:

    public SomeConsumer()
    {
        INavigationService service = null;
        service.NavigateAsync<SomeViewModel, OneParam>(new OneParam());
    }

为此:

    public SomeConsumer()
    {
        INavigationService service = null;
        service.NavigateAsync<SomeViewModel>(new OneParam());
    }

或此

    public SomeConsumer()
    {
        INavigationService service = null;
        service.NavigateAsync<SomeViewModel>(new TwoParam());
    }

但要防止此情况

    public SomeConsumer()
    {
        INavigationService service = null;
        service.NavigateAsync<SomeViewModel>(new ThreeParam());
    }

设置如下:

    public interface INavigationReceiver<TNavigationArgument>
        where TNavigationArgument : INavigationArgument
    {
        Task NavigateAsync(TNavigationArgument argument);
    }

    public interface INavigationArgument
    {

    }

    public class OneParam : INavigationArgument
    {
        public int Value1 { get; set; }
    }
    public class TwoParam : INavigationArgument
    {
        public int Value1 { get; set; }
        public int Value2 { get; set; }
    }
    public class ThreeParam : INavigationArgument
    {
        public int Value1 { get; set; }
        public int Value2 { get; set; }
    }

    public class SomeViewModel : INavigationReceiver<OneParam>, INavigationReceiver<TwoParam>
    {
        /// <inheritdoc />
        public async Task NavigateAsync(OneParam argument)
        {
            throw new System.NotImplementedException();
        }

        /// <inheritdoc />
        public async Task NavigateAsync(TwoParam argument)
        {
            throw new System.NotImplementedException();
        }
    }

    public interface INavigationService
    {
        Task NavigateAsync<TReceiver, TArgument>(TArgument argument)
            where TReceiver : INavigationReceiver<TArgument>
            where TArgument : INavigationArgument;
    }

    public class SomeConsumer
    {
        public SomeConsumer()
        {
            INavigationService service = null;
            service.NavigateAsync<SomeViewModel, OneParam>(new OneParam());
        }
    }

如果没有概念,这是可能的,我真的很想知道。

1 个答案:

答案 0 :(得分:1)

我不确定这是否能解决您的问题,但基于C#的当前功能,我认为以下内容可能与您想要的最接近:

public interface INavigationService
{
    //The implementation of this would simply create an instance
    //of something similar to the NavigationServiceStep2 class and return it
    INavigationServiceStep2<TArgument> NavigateAsync<TArgument>(TArgument argument)
        where TArgument : INavigationArgument;
}

public interface INavigationServiceStep2<TArgument> where TArgument : INavigationArgument
{
    Task ForReceiver<TReceiver>() where TReceiver : INavigationReceiver<TArgument>;
}

public class NavigationServiceStep2<TArgument> : INavigationServiceStep2<TArgument>
    where TArgument : INavigationArgument
{
    private readonly TArgument argument;

    public NavigationServiceStep2(TArgument argument)
    {
        this.argument = argument;
    }

    public Task ForReceiver<TReceiver>() where TReceiver : INavigationReceiver<TArgument>
    {
        //real implementation here
    }
}

public class SomeConsumer
{
    public SomeConsumer()
    {
        INavigationService service = null;
        service.NavigateAsync(new OneParam()).ForReceiver<SomeViewModel>();
    }
}

由于C#当前不允许您指定某些类型参数并自动推断其他类型参数,因此,唯一的方法是将单个方法调用转换为两个方法调用。

为此,有一个值得推荐的建议:https://github.com/dotnet/csharplang/issues/1349