基于字符串为多个属性选择值

本文关键字:属性 选择 字符串 | 更新日期: 2023-09-27 17:55:58

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

必须为每个文件分配以下属性:帐户名、市场活动名称、文档名称和目标名称。帐户和广告系列经常在类似文件之间共享,但文档几乎总是唯一的。有关示例,请参见下文。

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 语句的情况下解决这个问题?根据我的需要,我的问题有更好的名称吗?

基于字符串为多个属性选择值

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

    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。

好的,所以每个参数都是与每种动物相关的一对多关系。我的解决方案是为每个参数创建字典,并具有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
        };
}

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

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

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

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);
        }
    }
}

一种方法是使用工厂或原型。这样,您可以将此代码委托给另一个项目并执行任何操作。