3

我正在构建一个自动化的工作流系统,它必须根据正在读取的文件的名称设置 4 个字符串值。我有一个有效的 switch 语句,但正如您将在示例中看到的那样,我在不同的文件名之间有很多共享值。我正在寻找一种方法来简化此代码,因为很快我将有多达 40 个不同的文件名可供使用。

必须为每个文件分配以下属性:AccountName、CampaignName、DocumentName 和 DestinationName。帐户和活动经常在相似文件之间共享,但文档几乎总是唯一的。请参阅下面的示例。

case "Cow":
    accountName = "Farm Animals";
    campaignName = "Quadrupeds";
    documentName = "Milk Givers";
    destinationName = "Milking Line";
    break;
case "Chicken":
    accountName = "Farm Animals";
    campaignName = "Bipeds";
    documentName = "Egg Layers";
    destinationName = "Coupe";
    break;
case "Turkey":
    accountName = "Farm Animals";
    campaignName = "Bipeds";
    documentName = "Dinner";
    destinationName = "My Table";
    break;
case "Dog":
    accountName = "Farm Animals";
    campaignName = "Quadrupeds";
    documentName = "Best Friend";
    destinationName = "Front Porch";
    break;
case "Pig":
    accountName = "Farm Animals";
    campaignName = "Quadrupeds";
    documentName = "Bacon";
    destinationName = "My Plate";
    break;

我不知道字典是否是我正在寻找的,或者我是否会构建一个自定义类,我可以使用 LINQ 选择值,这就是我在这里的原因。

我想减少值的重复以使其更易于管理。类似于微关系数据库的东西,用于保存不同的值以及属于它们的文档。

我的问题是:有没有更好的方法可以在没有 switch 语句的情况下解决这个问题?根据我的需要,我的问题是否有更好的名称?

4

5 回答 5

3

您可以使用如下所述的字典:-

    public  class ElementName
    {
        public string AccountName { get; set; }
        public string CampaignName { get; set; }
        public string DocumentName { get; set; }
        public string DestinationName { get; set; }
    }
        var animalNameDict = new Dictionary<string, ElementName>
            {
                {
                    "cow",
                    new ElementName
                        {
                            AccountName = "Farm Animals",
                            CampaignName = "Quadrupeds",
                            DocumentName = "Milk Givers",
                            DestinationName = "Milking line"
                        }
                }
            };
        ElementName elem = null;
        animalNameDict.TryGetValue("cow", out elem);

        var item = animalNameDict.FirstOrDefault(x => x.Key == "cow");

或者您可以将其转换为类列表并使用 linq 扩展 ToLookup。

于 2013-01-25T19:50:16.357 回答
2

好的,所以每个参数都是与每只动物相关的一对多关系。我的解决方案是为每个参数创建字典,类型为Dictionary<string, List<string>>,如下所示:

var accountNames = new Dictionary<string, List<string>>
    {
        {"Farm Animals", new List<string> {"Cow", "Chicken", "Turkey", "Dog", "Pig"}}
    };

然后您将以类似于此的方式使用它(此示例使用匿名类型)。您可能希望为值检索创建一个扩展方法以清理代码并使其不区分大小写。

foreach(var animal in animals)
{
    var item = new
        {
            AccountName = accountNames.First(x => x.Value.Contains(animal)).Key
        };
}
于 2013-01-25T20:17:17.313 回答
1

您可以考虑使用反射来使用工厂来创建动物:

namespace mynamespace
{
    public class FarmAnimal
    {
        public string accountName = "Farm Animals";
    }
    public class Quadruped : FarmAnimal
    {
        public string campaignName = "Quadrupeds";
    }
    public class Dog : Quadruped
    {
        public string documentName = "Best Friend";
        public string destinationName = "Front Porch";

        public override string ToString()
        {
            return String.Format("{0} : {1} : {2} : {3}", accountName, campaignName, documentName, destinationName);
        }
    }

    public class AnimalFactory
    {
        public static FarmAnimal create(string fileName)
        {
            try {
                ObjectHandle h = Activator.CreateInstance(null, "mynamespace." + fileName);
                return  (FarmAnimal)h.Unwrap();
            }
            catch (Exception) {
                return null;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            FarmAnimal a = AnimalFactory.create("Dog");
            Console.WriteLine(a);
        }
    }
}
于 2013-01-25T20:11:23.560 回答
1

确实没有办法减少代码行数,因为如果不将某些东西连接到某个地方,就无法知道什么accountNamecampaignName选择什么。您可以像 TYY 建议的那样设置字典,但它仍然需要为每个文件(类型?)分配四个分配。

无论哪种方式,我都建议至少在某处将常用字符串(例如"Farm Animals"and "Quadrupeds")定义为常量,以减少 type-os 的机会并在需要时更容易更改。

于 2013-01-25T20:06:40.030 回答
0

An approach would be to use the Factory or Prototype. This way you can delegate this code to another project and do whatever you want.

于 2013-01-25T19:40:59.240 回答