避免在C#中进行多个函数调用

时间:2015-04-21 07:21:32

标签: c#

目前用C#编码,我想知道是否有一种方法可以将代码考虑在内,如下所示

Entity1 = GetByName("EntityName1");
Entity2 = GetByName("EntityName2");
Entity3 = GetByName("EntityName3");

想法是在代码中进行单个调用,通过将entitiesstrings放在容器中并在此容器上迭代以获得单个"来对代码进行分解。 GetByName()"线。有没有办法做到这一点?

4 个答案:

答案 0 :(得分:27)

您可以使用LINQ:

var names=new[]{"EntityName1","EntityName2","EntityName3",.....};
var entities=names.Select(name=>GetByName(name)).ToArray();

如果没有ToArraySelect将返回一个IEnumerable,每次枚举时都会重新评估它 - 也就是说,每次枚举可枚举时都会调用GetByName

ToArray()ToList将创建一个可以多次使用的数组(或列表)。

如果您希望能够按名称访问实体,也可以致电ToDictionary

var entities=names.ToDictionary(name=>name,name=>GetByName(name));

所有这些都假定实体尚未存在或GetByName必须做一些重要的工作来检索它们。如果实体存在,您只需将它们放在Dictionary<String,Entity>中即可。如果实体具有Name属性,则可以使用ToDictionary在一个语句中创建字典:

var entities=new []{entity1,entity2,entity3,...};
var entitiesDict=entities.ToDictionary(entity=>entity.Name,entity=>entity);

答案 1 :(得分:10)

您的意思是如下所示(其中entitiesEntity1Entity1&amp; Entity3的集合:

var results = entities.Select(e => GetByName(e.Name));

答案 2 :(得分:7)

这取决于你在寻找什么。如果您需要在一行中设置变量,那将无效。如果你正在处理字段或属性,你可以玩反射,但老实说,这看起来比你已经变得更加混乱。

如果数据结构无关紧要,并且您只需要数据并且能够在您认为合适时使用它,我可能会将其枚举为字典。当然,这与你现在所拥有的非常紧密相关,无论如何看起来它都是假的实现。

如果你想这样做,那就非常简单了。您可以选择如何创建IEnumerable<string>,其代表如下entityNames。您可以像我一样使用数组初始值设定项,您可以使用随时间构建的List<string>,甚至可以使用自己的方法yield return

var entityNames = new[] { "EntityName1", "EntityName2", "EntityName3" };

var dict = entityNames.ToDictionary(c => c, c => GetByName(c));

然后只是检查那些。

var entity1 = dict["EntityName1"];

或列举字典。

foreach(var kvp in dict)
{
    Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value);
}

但实际上,很难知道这是否比你已经拥有的更好。

答案 3 :(得分:3)

好的,这是一个想法。

您可以声明此功能。

IReadOnlyDictionary<string, T> InstantiateByName<T>(
        Func<string, T> instantiator
        params string[] names)
{
    return names.Distinct().ToDictionary(
        name => name,
        name => instantiator(name))
}

你可以像这样打电话,

var entities = InstantiateByName(
         GetByName,
         "EntityName1",
         "EntityName2",
         "EntityName3");

将过度工程推向新的水平,

您可以安装Immutable Collections包,

PM> Install-Package Microsoft.Bcl.Immutable

并稍微修改一下这个功能,

using Microsoft.Immutable.Collections;

IReadOnlyDictionary<string, T> InstantiateByName<T>(
        Func<string, T> instantiator
        params string[] names,
        IEqualityComparer<string> keyComparer = null,
        IEqualityComparer<T> valueComparer = null)
{
    if (keyComparer == null)
    {
        keyComparer = EqualityComparer<string>.Default;
    }

    if (valueComparer == null)
    {
        valueComparer = EqualityComparer<T>.Default;
    }

    return names.ToImmutableDictionary(
        name => name,
        name => instantiator(name),
        keyComparer,
        valueComparer);
}

该功能将以完全相同的方式使用。但是,调用者负责将唯一键传递给函数,但是可以传递另一个相等比较器。