我有一个接受请求并提供响应的通用方法.
public Tres DoSomething<Tres, Treq>(Tres response, Treq request)
{/*stuff*/}
Run Code Online (Sandbox Code Playgroud)
但我并不总是希望对我的请求做出回应,而且我并不总是希望提供请求数据以获得响应.我也不想完整地复制和粘贴方法以进行微小的更改.我想要的是能够做到这一点:
public Tre DoSomething<Tres>(Tres response)
{
return DoSomething<Tres, void>(response, null);
}
Run Code Online (Sandbox Code Playgroud)
这在某种程度上是可行的吗?似乎专门使用void不起作用,但我希望找到类似的东西.
das*_*ght 85
你不能使用void,但你可以使用object:它有点不方便,因为你的void功能需要返回null,但如果它统一你的代码,它应该是一个很小的代价.
这种无法void用作返回类型至少部分地负责一般代表Func<...>和Action<...>一系列代表之间的分离:如果有可能返回void,一切Action<X,Y,Z>都会变得简单Func<X,Y,Z,void>.不幸的是,这是不可能的.
Jon*_*eet 81
不,不幸的是没有.如果void是"真实"类型(例如unit在F#中),生活在很多方面会简单得多.特别是,我们不会同时需要Func<T>和Action<T>家庭-有好多只是Func<void>代替Action,Func<T, void>而不是Action<T>等
它也会使异步变得更简单 - 根本不需要非泛型Task类型 - 我们只需要Task<void>.
不幸的是,这不是C#或.NET类型系统的工作方式......
Tri*_*Gao 25
这是你可以做的.正如@JohnSkeet所说,C#中没有单位类型,所以自己动手吧!
public sealed class ThankYou {
private ThankYou() { }
private readonly static ThankYou bye = new ThankYou();
public static ThankYou Bye { get { return bye; } }
}
Run Code Online (Sandbox Code Playgroud)
现在你可以随时使用Func<..., ThankYou>而不是Action<...>
public ThankYou MethodWithNoResult() {
/* do things */
return ThankYou.Bye;
}
Run Code Online (Sandbox Code Playgroud)
或者使用Rx团队已经制作的东西:http://msdn.microsoft.com/en-us/library/system.reactive.unit%28v=VS.103%29.aspx
Jep*_*sen 15
您可以Object像其他人建议的那样使用.或者Int32我看到了一些用途.使用Int32引入了一个"虚拟"数字(使用0),但至少你不能将任何大而奇特的对象放入Int32引用(结构被密封).
你也可以写自己的"void"类型:
public sealed class MyVoid
{
MyVoid()
{
throw new InvalidOperationException("Don't instantiate MyVoid.");
}
}
Run Code Online (Sandbox Code Playgroud)
MyVoid允许引用(它不是静态类)但只能是null.实例构造函数是私有的(如果有人试图通过反射调用此私有构造函数,则会抛出异常).
我喜欢上面的Aleksey Bykov的想法,但它可以简化一点
public sealed class Nothing {
public static Nothing AtAll { get { return null; } }
}
Run Code Online (Sandbox Code Playgroud)
因为我没有明显的理由为什么Nothing.AtAll不能只给null
同样的想法(或Jeppe Stig Nielsen的想法)对于使用类型类也很有用.
例如,如果类型仅用于描述作为某个方法的参数传递的过程/函数的参数,并且它本身不接受任何参数.
(你仍然需要制作一个虚拟包装器或允许一个可选的"Nothing".但恕我直言,类使用看起来很好用myClass <Nothing>)
void myProcWithNoArguments(Nothing Dummy){
myProcWithNoArguments(){
}
Run Code Online (Sandbox Code Playgroud)
要么
void myProcWithNoArguments(Nothing Dummy=null){
...
}
Run Code Online (Sandbox Code Playgroud)