标签: params-keyword

Clojure关键字参数

在Common Lisp中你可以这样做:

(defun foo (bar &key baz quux)
  (list bar baz quux))

(foo 1 :quux 3 :baz 2) ; => (1 2 3)
Run Code Online (Sandbox Code Playgroud)

Clojure没有关键字参数.一种选择是:

(defn foo [bar {:keys [baz quux]}] 
  (list bar baz quux))

(foo 1 {:quux 3 :baz 2}) ; => (1 2 3)
Run Code Online (Sandbox Code Playgroud)

这是太多的嵌套括号,必须一直打字和阅读.它还需要将显式散列映射作为参数而不是平面列表传递.

什么是最惯用的Clojure相当于关键字参数,看起来没有人引发标点炸弹?

lisp binding clojure common-lisp params-keyword

52
推荐指数
3
解决办法
1万
查看次数

我可以在Action或Func委托中使用params吗?

当我试图在Action委托中使用params时......

private Action<string, params object[]> WriteToLogCallBack;
Run Code Online (Sandbox Code Playgroud)

我收到了这个设计时错误:

类,结构或接口成员声明中的标记'params'无效

任何帮助!

c# delegates action params-keyword

39
推荐指数
3
解决办法
2万
查看次数

在方法覆盖中更改params修饰符

我知道params修饰符(将数组类型的一个参数转换为所谓的"参数数组")特别不是方法签名的一部分.现在考虑这个例子:

class Giraffid
{
    public virtual void Eat(int[] leaves)
    {
        Console.WriteLine("G");
    }
}
class Okapi : Giraffid
{
    public override void Eat(params int[] leaves)
    {
        Console.WriteLine("O");
    }
}
Run Code Online (Sandbox Code Playgroud)

编译时没有任何警告.然后说:

var okapi = new Okapi();
okapi.Eat(2, 4, 6);  // will not compile! 
Run Code Online (Sandbox Code Playgroud)

给出一个错误(No overload for method 'Eat' takes 3 arguments).

现在,我知道编译器会将params修改器转换为System.ParamArrayAttribute相关参数的应用程序.通常,将一个属性集合应用于虚方法的参数,然后在具有不同属性集的派生类中的重写方法中装饰"对应"参数是没有问题的.

然而,编译器选择params静默忽略我的关键字.相反,如果一个使它反过来,并且应用于params基类中的参数Giraffid,然后省略覆盖中的关键字Okapi,编译器选择用它来装饰两个方法System.ParamArrayAttribute.当然,我用IL DASM验证了这些东西.

我的问题:

这是记录在案的行为?我已经彻底搜索了C#语言规范,但没有发现任何提及.

我可以说至少Visual Studio开发环境对此感到困惑.当键入2, 4, 6在上述方法的调用,所述 …

c# overriding virtual-functions params-keyword params

16
推荐指数
2
解决办法
1121
查看次数

使用C#的XML注释cref属性和params语法

在C#中,我试图使用<see cref ="blah"/>来引用包含params关键字的方法签名.我知道这会将参数列表转换为数组,但我甚至无法弄清楚如何在CREF属性中引用数组.我在搜索中找不到任何内容,也不知道我知道的任何人.编译器在方括号上窒息.我已经尝试了各种不同的组合,使用花括号,使用Array类,但没有任何工作.有谁知道这个?

c# params-keyword xml-comments

15
推荐指数
3
解决办法
1万
查看次数

params []可以作为lambda表达式的参数吗?

我最近开始探索lambda表达式,我想到了一个问题.假设我有一个需要不确定数量参数的函数.我会使用params关键字来建模可变数量的参数.

我的问题:我可以用Lambda表达式做类似的事情吗?例如:

Func<int[], int> foo = (params numbers[]) =>
                       {
                           int result;

                           foreach(int number in numbers)
                           {
                               result += numbers;
                           }

                           return result;
                       }
Run Code Online (Sandbox Code Playgroud)

如果是这样,两个子问题就出现了 - 是否有一种'好'的方式来编写这样的表达式,我甚至想在某个时候写出这样的表达式?

c# lambda closures params-keyword

11
推荐指数
1
解决办法
6242
查看次数

如何在C#中使用params关键字和调用者信息?

我正在尝试将C#5.0来电者信息与C#params关键字结合起来.目的是为日志框架创建一个包装器,我们希望记录器像String.Format一样格式化文本.在以前的版本中,方法如下所示:

void Log(
   string message,
   params object[] messageArgs = null);
Run Code Online (Sandbox Code Playgroud)

我们称之为:

log.Log("{0}: I canna do it cap'n, the engines can't handle warp {1}!", 
        "Scotty", warpFactor);
Run Code Online (Sandbox Code Playgroud)

现在,我们想要捕获调用者信息并记录它们.签名变为:

void Log(
    string message,
    params object[] messageArgs,
    [CallerMemberName] string sourceMemberName = null);
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为参数必须是最后一个参数.所以我试试这个:

void Log(
    string message,
    [CallerMemberName] string sourceMemberName = null,
    params object[] messageArgs);
Run Code Online (Sandbox Code Playgroud)

有没有办法在没有提供sourceMembername的情况下调用它,或者将messageArgs参数显式指定为命名参数?这样做会破坏params关键字的用途:

// params is defeated:
log.Log("message", 
        messageArgs: new object[] { "Scotty", warpFactor });
// CallerMemberName is defeated:
log.Log("message", null,
        "Scotty", warpFactor);
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?似乎传递调用者信息的"hacky"方式排除了使用params关键字.如果C#编译器认识到调用者成员信息参数根本不是真正的参数,那将是很棒的.我认为没有必要明确地传递它们.

我的备份将跳过params关键字,并且调用者必须在最后一个示例中使用长签名.

c# params-keyword callermembername

9
推荐指数
2
解决办法
1604
查看次数

如何确保使用'params'关键字的签名更改时出现编译错误

我有这样的方法:

public void Foo(params string[] args) {
  bar(args[0]); 
  bar(args[1]);
}
Run Code Online (Sandbox Code Playgroud)

新要求会导致这样的变化:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    bar(args[0]); 
    bar(args[1]);
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是即使我已经更改了方法签名,也没有发生编译错误,当然这是正确的,但是我希望每次调用没有指定Foo参数的方法时都会出现编译错误baz.也就是说,如果Foo在更改之前的呼叫是这样的:

Foo(p1,p2); //where p1 and p2 are strings
Run Code Online (Sandbox Code Playgroud)

它现在需要是这个:

Foo(baz,p1,p2);
Run Code Online (Sandbox Code Playgroud)

如果它不会以这种方式改变,p1则将被赋值给baz,并且params数组args的长度为1,并且OutOfBounds将抛出异常.

更改签名并确保所有调用代码都相应更新的最佳方法是什么?(真实场景是Foo许多项目共享的程序集中的生命自动构建在构建服务器上.编译错误因此是检测需要触及的所有代码以容纳更改的简单方法.)

编辑: 正如Daniel Mann和其他人指出的那样,上面的例子表明我根本不应该使用params.所以我应该解释一下,在我的真实世界的例子中,并不总是args需要有两个元素的情况,就Foo中的逻辑而言,args可以包含任意数量的元素.所以我们说这是Foo:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    int x = GetANumberDynamically();
    for(int i = 0; i<x; i++)
      bar(args[i]); 
  } …
Run Code Online (Sandbox Code Playgroud)

c# params-keyword

8
推荐指数
1
解决办法
151
查看次数

String.Format() - 重新传递参数但添加更多参数

我想做那样的事情:

public string GetMessage(params object otherValues[]) {
    return String.Format(this.Message, this.FirstValue, otherValues);
}
Run Code Online (Sandbox Code Playgroud)

所以,我想修复一系列参数,String.Format()但添加一个新参数.

什么是最好的方法,知道我们可以"重建"一个新的对象数组,这似乎并不好.

.net c# string-formatting params-keyword

6
推荐指数
1
解决办法
9993
查看次数

使用"params"关键字的方法的几个重载

我看了一下Path.Combine,注意到它有四个重载:

  1. string, string
  2. string,string,string
  3. string,string,string,string
  4. params string[]

前三个重载如何有用?
我看到它的方式,第四次超载使其他人毫无意义.我查看了源代码,我确实看到第四个重载的实现有点不同,但即使在这种情况下,我也希望只有一个params重载决定根据数组的长度使用哪个实现.

.net c# overloading params-keyword

5
推荐指数
1
解决办法
1280
查看次数

为什么我不能有两个方法签名,唯一的区别是数组参数的“params”关键字?

public class SomeClass
{
    public SomeClass(SomeType[] elements)
    {
        
    }
    public SomeClass(params SomeType[] elements)
    {
        
    }
}
Run Code Online (Sandbox Code Playgroud)

我打印了这段代码并得到了CS0111错误。我很奇怪,难道SomeType[] elementsparams SomeType[] elements同样的说法?

c# params-keyword

5
推荐指数
2
解决办法
104
查看次数