void in C# generics?

后端 未结 7 1981
小蘑菇
小蘑菇 2020-12-13 03:11

I have a generic method that takes a request and provides a response.

public Tres DoSomething(Tres response, Treq request)
{/*stuff*/}


        
相关标签:
7条回答
  • 2020-12-13 03:39

    void, though a type, is only valid as a return type of a method.

    There is no way around this limitation of void.

    0 讨论(0)
  • 2020-12-13 03:40

    What I currently do is create custom sealed types with private constructor. This is better than throwing exceptions in the c-tor because you don't have to get until runtime to figure out the situation is incorrect. It is subtly better than returning a static instance because you don't have to allocate even once. It is subtly better than returning static null because it is less verbose on the call side. The only thing the caller can do is give null.

    public sealed class Void {
        private Void() { }
    }
    
    public sealed class None {
        private None() { }
    }
    
    0 讨论(0)
  • 2020-12-13 03:42

    You cannot use void, but you can use object: it is a little inconvenience because your would-be-void functions need to return null, but if it unifies your code, it should be a small price to pay.

    This inability to use void as a return type is at least partially responsible for a split between the Func<...> and Action<...> families of generic delegates: had it been possible to return void, all Action<X,Y,Z> would become simply Func<X,Y,Z,void>. Unfortunately, this is not possible.

    0 讨论(0)
  • 2020-12-13 03:44

    I like the idea by Aleksey Bykov above, but it could be simplified a bit

    public sealed class Nothing {
        public static Nothing AtAll { get { return null; } }
    }
    

    As I see no apparent reason why Nothing.AtAll could not just give null

    The same idea (or the one by Jeppe Stig Nielsen) is also great for usage with typed classes.

    E.g. if the type is only used to describe the arguments to a procedure/function passed as an argument to some method, and it itself does not take any arguments.

    (You will still need to either make a dummy wrapper or to allow an optional "Nothing". But IMHO the class usage looks nice with myClass<Nothing> )

    void myProcWithNoArguments(Nothing Dummy){
         myProcWithNoArguments(){
    }
    

    or

    void myProcWithNoArguments(Nothing Dummy=null){
        ...
    }
    
    0 讨论(0)
  • 2020-12-13 03:49

    No, unfortunately not. If void were a "real" type (like unit in F#, for example) life would be a lot simpler in many ways. In particular, we wouldn't need both the Func<T> and Action<T> families - there'd just be Func<void> instead of Action, Func<T, void> instead of Action<T> etc.

    It would also make async simpler - there'd be no need for the non-generic Task type at all - we'd just have Task<void>.

    Unfortunately, that's not the way the C# or .NET type systems work...

    0 讨论(0)
  • 2020-12-13 03:49

    Here is what you can do. As @JohnSkeet said there is no unit type in C#, so make it yourself!

    public sealed class ThankYou {
       private ThankYou() { }
       private readonly static ThankYou bye = new ThankYou();
       public static ThankYou Bye { get { return bye; } }
    }
    

    Now you can always use Func<..., ThankYou> instead of Action<...>

    public ThankYou MethodWithNoResult() {
       /* do things */
       return ThankYou.Bye;
    }
    

    Or use something already made by the Rx team: http://msdn.microsoft.com/en-us/library/system.reactive.unit%28v=VS.103%29.aspx

    0 讨论(0)
提交回复
热议问题