【问题标题】:Call a method after statements have been evaluated在评估语句后调用方法
【发布时间】:2013-01-09 22:39:16
【问题描述】:

这应该很容易回答,但我什至不知道如何正确地问它,所以我提前为我的 n00b-ness 道歉。对于没有运气的搜索,我一直在努力解释它......

基本上我有一个方法,它接受几个参数作为“开关”(由调用方法设置为 0 或 1)和可选字符串,并使用它们来“构建”其行动计划。它是这样的:

public static void Foo(int a, int b, int c, optionalString aa, optionalString, bb, optionalString cc)
{
    if (a == 1)
    { Object1 o1 = Thing.Property1[aa]; }
    if (b == 1)
    { Object2 o2 = Thing.Property2[bb]; }
    if (c == 1)
    { Object3 o3 = Thing.Property3[cc]; }

    Bar(optionalo1, optionalo2, optionalo3); // Edit: I explained this part a little wrong, see below.
}

编辑澄清:我不能将空值传递给Bar(),因为它只需要使用实际设置的属性来调用。例如,调用 Foo() 时设置的 a、b 和 c 如下所示:

Foo(1, 0, 1, string1, string3) //In this instance I only want the first and third properties set. The strings contain the values I want them set to.
{
    if (a == 1)
    { set this property based on string1 }
    if (b == 1)
    { this one would not be set because b was 0 }
    if (c == 1)
    { set this property based on string3 }

    Bar(property1, property3);
    // In this instance, Bar() must be called with only those two arguments, it cannot contain any null values.

编辑结束

所以,如果不对Bar() 的每个可能组合使用大量嵌套的if() 语句或方法,有没有办法在所有这些都被评估后调用它?从技术上讲,尚未分配变量,因此Bar() 无效。或者,有没有更好的方法来完成这样的事情?

这适用于与 SharePoint 服务器对象模型交互的控制台应用程序,如果这有什么不同的话。非常感谢您的宝贵时间!

【问题讨论】:

  • 首先,一个可以为 0 或 1 的“开关”不是 int,它是 bool
  • 另外,那些字符串参数在严格意义上不是可选的,为什么不直接使用string aa == null,如果它的null 不使用呢?
  • 你的问题很难理解。似乎除了您在示例代码中遇到的一些奇怪的命名问题外,它完全符合您的要求。
  • 贴一些相关代码,看到IFoo, Foo & Bar 感觉像个外星人
  • 你不能用泛型解决这个问题吗?

标签: c# methods sharepoint-2010 optional-arguments


【解决方案1】:

也许您只想将 null 作为默认值传递给 Bar 方法,如下所示:

public static void Foo(int a, int b, int c, 
    optionalString aa, optionalString, bb, optionalString cc)
{
    Object1 o1 = null;
    Object1 o2 = null;
    Object1 o3 = null;
    if (a == 1)
    { o1 = Thing.Property1[aa]; }
    if (b == 1)
    { o2 = Thing.Property2[bb]; }
    if (c == 1)
    { o3 = Thing.Property3[cc]; }

    Bar(o1, o2, o3);
}

【讨论】:

  • 不幸的是,对 Bar() 的调用不能包含任何空值。请参阅我的编辑以进行澄清。
【解决方案2】:

您需要将代码转换为数据。您有一些输入参数,需要对它们执行一些操作。

使用定义为Dictionary<Key, Action> 的字典结构,您可以在其中创建Key = whatever unique value。那么你在你的方法中所要做的就是计算key并执行相关的动作。

从你的例子:

    public static void Foo(int a, int b, int c, optionalString aa, optionalString, bb, optionalString cc)
    {
Dictionary<int, Action> objectMapper = new Dictionary<int, Action>
        {
            { 0, () => Bar() },
            { 1, () => Bar(Thing.Property1[aa]) },
            { 2, () => Bar(Thing.Property2[bb]) },
            { 4, () => Bar(Thing.Property3[cc]) },
            { 3, () => Bar(Thing.Property1[aa], Thing.Property2[bb]) },
            { 5, () => Bar(Thing.Property1[aa], Thing.Property3[cc]) },
            { 6, () => Bar(Thing.Property2[bb], Thing.Property3[cc]) },
            { 7, () => Bar(Thing.Property1[aa], Thing.Property2[bb], Thing.Property3[cc]) },
        };    
        objectMapper[a & b & c]();
    }

在我的示例中,唯一键就是ANDing 3 个输入变量。但是,如您所见,涵盖所有可能性非常繁琐,这就是为什么我不建议完全这样做的原因,而是尝试重新设计您的 Bar 方法以在输入参数上更加灵活。

【讨论】:

  • 啊,如果所有其他方法都失败了,这看起来是一种更简洁的方法来完成我的目标。感谢您的选择!不幸的是,Bar() 方法实际上代表了对特定于 SharePoint 的各种对象索引的一系列操作,但在这种情况下,它的调用方式与常规方法相同,并且不灵活。如果没有用参数的确切数量和组合调用它,它就会爆炸。如果不重写一堆 SharePoint 程序集,我就无法改变它的工作方式。
  • @thanby,lambda 表达式可以是您想要的任何语句序列。但是,如果您只有一个公共 API 调用,那么您实际上没有太多选择。如果您喜欢我的方法,那么很高兴认识它。 :)
  • 到目前为止,它是答案的最佳竞争者! (我还没有代表投票,否则我会)
【解决方案3】:

取决于 Bar 的签名,是的。

如果 bar 被声明为类似

public static void Bar(params string[] values) {
    foreach(var v in values) {
        // use value
    }
}

然后 Foo 可以构建一个数组并发送它,例如

var list values = new List<string>();

if(a == 1) {
    list.Add(optionalo1);
    // do whatever else
}

if(b == 1) {
    list.Add(optionalo2);
    // do whatever else
}

Bar(values.ToArray());

编辑:

还要记住,如果 Foo 被声明为

public static void Foo(int a, int b, int c, string aa = null, string bb = null, string cc = null)

并且您像在示例中那样调用它:

Foo(1, 0, 1, string1, string3)

然后 string1 将按照您的意愿在 string1 中结束,但传递的 string3 将在 string2 中结束。您需要将该位置的 null 传递给 Foo ,否则这些值会混淆。

【讨论】:

  • Foo() 的调用指定了参数,例如(string1: firstString, string3: thirdString) ...我做对了,不是吗?就像我说的,我是这门语言的新手。 Bar() 不能接受数组,但也许我可以使用数组来构建对它的调用来表达参数的组合? (如果有道理的话)
  • 是的,如果你将参数命名为 Foo,你会没事的。我不确定您对 C# 的熟悉程度,因此如果我在解释您已经知道的内容,我深表歉意,但是像这样声明 Bar 并不会将其限制为仅接收数组。它将接受数组和单独传递的值,即您仍然可以使用参数列表调用它。你可以在这里找到信息:msdn.microsoft.com/en-us/library/w5zay9db.aspx。如果您要执行的操作涉及可变数量的参数,其中任何一个都不能为空,我认为您需要使用参数。
  • 从阅读那篇 msdn 文章看来,params 可能是解决我的问题的一种方法。我会试试看什么效果最好。感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多