有趣的“参数参数”function,任何解决方法?
我想知道是否有任何方式这样的事情是可能的价值types…
public static class ExtensionMethods { public static void SetTo(this Boolean source, params Boolean[] bools) { for (int i = 0; i < bools.Length; i++) { bools[i] = source; } } }
那么这将是可能的:
Boolean a = true, b, c = true, d = true, e; b.SetTo(a, c, d, e);
当然,这是行不通的,因为bools是一个值types,所以它们被作为一个值传递给函数,而不是作为参考。
除了将值types包装到引用types中(通过创build另一个类),有没有办法通过引用(ref)将parameter passing给函数,而使用params修饰符?
这不可能。 为了解释为什么,首先阅读我的论文,为什么我们通过将它们放在堆栈上来优化值types局部variables的释放:
现在你明白了,应该清楚为什么你不能在数组中存储“ref bool”。 如果可以的话,那么你可以有一个比被引用的栈variables长的数组。 我们有两个select:要么允许这样做,要么产生一些程序,如果你弄错了就会崩溃死亡 – 这是由C的devise者做出的select,或者禁止它,并且有一个不那么灵活但更多的系统安全。 我们select了后者。
但是让我们更深入地思考一下。 如果你想要传递的是“允许我设置variables的东西”,那么我们就是这样 。 这只是一个代表:
static void DoStuff<T>(this T thing, params Action<T> actions) { foreach(var action in actions) action(thing); } ... bool b = whatever; b.DoStuff(x=>{q = x;}, x=>{r = x;} );
合理?
不幸的是,Java社区,现在的.NET,开发人员认为,“安全”这个名字的灵活性较低是首选的解决scheme,为了达到相同的结果,用较less的代码行,你必须select非常复杂的(所有这些类结构,代表等)。
在Delphi中,我可以简单地做这样的事情:
var a: integer; f: double; n: integer; sscanf(fmtstr, valuestr, [@a, @f, @n]);
// < – “sscanf”是我自己写的一个函数,它需要一个开放的指针数组。
在C#中你将不得不这样做:
int a; double f; int n; object [] o = new object[]; sscanf(fmtstr, valuestr, ref o); a = o[0]; f = o[1]; n = o[2];
这是5行代码,可以在1行Delphi代码中完成我所能做的事情。 我认为有一个公式的地方,代码中的错误的可能性增加几何的代码行数; 所以如果你有20行代码,你的代码比有10个代码的可能性要高出4倍。
当然,你可以通过使用带有所有那些奇怪的尖括号和奇怪的语法的委托来减less你的#行代码,但是我认为这也是bug的天堂。
什么曾经发生过简单?
没有办法。 你可以做这样的事情:
public static void Main(string[] args) { BooleanWrapper a = true, b = true, c = true, d = true, e = new BooleanWrapper(); b.SetTo(a, c, d, e); } public static void SetTo(this BooleanWrapper sourceWrapper, params BooleanWrapper[] wrappers) { foreach (var w in wrappers) w.Value = sourceWrapper.Value; } public class BooleanWrapper { public BooleanWrapper() { } public BooleanWrapper(Boolean value) { Value = value; } public Boolean Value { get; set; } public static implicit operator BooleanWrapper(Boolean value) { return new BooleanWrapper(value); } }
但是,那又如何比这样做更好:
public static void Main(string[] args) { Boolean[] bools = new Boolean[5]; bools.SetTo(bools[1]); // Note I changed the order of arguments. I think this makes more sense. } public static void SetTo(this Boolean[] bools, Boolean value) { for(int i = 0; i < bools.Length; i++) bools[i] = value; }
毕竟,数组是一系列variables。 如果您需要某些行为类似于variables序列的内容,请使用数组。
即使bool
是参考types,这也是不可能的。 虽然一个class
是一个引用types,但是Boolean[]
的variables仍然是一个值 ,只是该值是一个引用 。 分配引用的值只会改变特定variables的值。 ref
variables数组的概念没有意义(因为数组本身就是一系列值)。