无效的C#generics?
我有一个通用的方法,接受请求并提供响应。
public Tres DoSomething<Tres, Treq>(Tres response, Treq request) {/*stuff*/}
但是我并不总是希望得到我的请求的响应,而且我也不总是希望提供请求数据来获得响应。 我也不想全部复制和粘贴方法做一些小改动。 我想要的是能够做到这一点:
public Tre DoSomething<Tres>(Tres response) { return DoSomething<Tres, void>(response, null); }
这在某种程度上是可行的吗? 看来专门使用void不起作用,但我希望能find类似的东西。
你不能使用void
,但是你可以使用object
:这有点不方便,因为你的void
函数需要返回null
,但是如果它统一了你的代码,它应该是一个小的代价。
这种无法使用void
作为返回types至less部分负责generics委托的Func<...>
和Action<...>
系列之间的分割:是否有可能返回void
,所有的Action<X,Y,Z>
将变成简单的Func<X,Y,Z,void>
。 不幸的是,这是不可能的。
不,不幸的不是。 如果void
是一个“真实”的types(比如F#中的unit
),那么在很多方面,生活将会变得简单得多。 特别是,我们不需要Func<T>
和Action<T>
系列 – 只需要Func<void>
而不是Action
, Func<T, void>
而不是Action<T>
等。
这也会使asynchronous更简单 – 根本就不需要非通用的Task
types – 我们只需要Task<void>
。
不幸的是,这不是C#或.NETtypes系统的工作方式。
这是你可以做的。 正如@JohnSkeet所说,C#中没有单元types,所以自己动手!
public sealed class ThankYou { private ThankYou() { } private readonly static ThankYou bye = new ThankYou(); public static ThankYou Bye { get { return bye; } } }
现在你可以使用Func<..., ThankYou>
而不是Action<...>
public ThankYou MethodWithNoResult() { /* do things */ return ThankYou.Bye; }
或者使用Rx团队已经完成的工作: http : //msdn.microsoft.com/en-us/library/system.reactive.unit%28v=VS.103%29.aspx
您可以简单地使用Object
如其他人所build议的。 或者我已经看到一些使用Int32
。 使用Int32
引入了一个“虚拟”数字(使用0
),但至less不能将任何大的和奇特的对象放入Int32
引用(结构被封闭)。
你也可以写你自己的“空白”types:
public sealed class MyVoid { MyVoid() { throw new InvalidOperationException("Don't instantiate MyVoid."); } }
MyVoid
引用是允许的(它不是一个静态类),但只能是null
。 实例构造函数是私有的(如果有人试图通过reflection来调用这个私有构造函数,将抛出exception)。
void
虽然是一个types,但仅作为方法的返回types有效。
void
这种限制void
。
我喜欢上面的Aleksey Bykov的想法,但可以简化一下
public sealed class Nothing { public static Nothing AtAll { get { return null; } } }
正如我看到没有明显的原因,为什么Nothing.AtAll不能只给零
同样的想法(或Jeppe Stig Nielsen的观点)也适用于input类。
例如,如果该types仅用于描述作为某个方法的parameter passing的过程/函数的参数,并且它本身不包含任何参数。
(你仍然需要制作一个虚拟包装器或允许一个可选的“Nothing”,但是恕我直言,类的使用看起来不错,myClass <Nothing>)
void myProcWithNoArguments(Nothing Dummy){ myProcWithNoArguments(){ }
要么
void myProcWithNoArguments(Nothing Dummy=null){ ... }