代码之家  ›  专栏  ›  技术社区  ›  Dbl

是否可以删除此方法的泛型参数?

  •  1
  • Dbl  · 技术社区  · 6 年前

    我正在尝试为我的视图模型创建一个导航服务-它只有一个问题。我希望我只是错过了一些事情/做错了一些事情,否则我想我必须等待 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 回复  |  直到 6 年前
        1
  •  1
  •   Yacoub Massad    6 年前

    我不确定这是否解决了您的问题,但我认为基于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