C#按优先级获取第一个非空属性

C#按优先级获取第一个非空属性,c#,C#,我目前拥有一个具有多个字符串属性的类。其中一个或多个可能有一个值。我需要做的是根据优先级获取第一个非空属性。下面是一个我设想的类的示例: public class MyClass { [Priority(1)] public string HighestPriority { get; set; } [Priority(2)] public string MiddlePriority { get; set; } [Priority(3)] pub

我目前拥有一个具有多个字符串属性的类。其中一个或多个可能有一个值。我需要做的是根据优先级获取第一个非空属性。下面是一个我设想的类的示例:

public class MyClass
{
    [Priority(1)]
    public string HighestPriority { get; set; }

    [Priority(2)]
    public string MiddlePriority { get; set; }

    [Priority(3)]
    public string LowestPriority { get; set; }
}
或者,可以使用另一个枚举属性来确定设置的最高值

public enum Priority
{
    HighestPriority,
    MiddlePriority,
    LowestPriority
}

public class MyClass
{
    private string highestPriority;
    public string HighestPriority 
    { 
        get; 
        set
        {
            highestPriority = value;
            HighestSetProperty = Priority.HighestPriority;
        }
    }

    private string middlePriority;
    public string MiddlePriority
    { 
        get; 
        set
        {
            middlePriority = value;
            if (HighestSetProperty != Priority.HighestPriority)
                HighestSetProperty = Priority.MiddlePriority;
        }
    }

    private string lowestPriority;
    public string LowestPriority
    { 
        get; 
        set
        {
            lowestPriority = value;
            if (HighestSetProperty != Priority.HighestPriority || HighestSetProperty != Priority.MiddlePriority)
                HighestSetProperty = Priority.LowestPriority;
        }
    }

    public Priority HighestSetProperty { get; set; }
}
然后,使用HighestSetProperty在switch语句中设置字符串

但是,到目前为止,我所知道的在不使用上述某种形式的优先级属性的情况下查找第一个非空属性的唯一方法是:

string highestPriorityProp = String.IsNullOrWhitespace(HighestPriority) ? (String.IsNullOrWhitespace(MiddlePriority) ? LowestPriority : MiddlePriority) : HighestPriority;
这显然是混乱的,如果添加更多属性,则无法很好地扩展。 那么,在可读性、速度和可伸缩性方面,最好的方法是什么?提前谢谢

编辑:让我们超越速度,追求清洁度和可扩展性

编辑:重复的问题实际上没有回答我的问题。因为属性可能不符合优先级顺序。因此,循环通过的第一个优先级可能比最高优先级低。 例如:

public class MyClass
{
    public string MiddlePriority { get; set; }

    public string HighPriority { get; set; }
}

编辑:谢谢大家的帮助。正如mjwills和我在评论中所讨论的,被接受的答案将适合我的需要,因为我班上只有大约6处房产。但是,如果还有更多的话,可能是最好的方法。

通常,您可以通过操作员执行以下操作:

var highest = high ?? medium ?? low;
    var highest = HighestPriority.ConvertEmptyToNull() ?? MediumPriority.ConvertEmptyToNull() ?? LowPriority.ConvertEmptyToNull();
但您似乎希望将“null”和“空字符串”视为相同的。因此,编写一个将空字符串转换为空字符串的函数:

Func<string,string> func = s => s == "" ? null : s;
我建议不要使用属性和反射。是的,当您添加一个新属性时,您必须修改代码,但是您已经在修改代码以添加属性本身——没有什么意义使只有一半的解决方案是自动的。虽然使用“灵活”的解决方案和反思是一种常见的诱惑,但根据我的经验,从长远来看,这通常会适得其反


如果你赞同自动缩放和吸收越来越多的属性的想法,我建议使用列表或字典,并使用类似的方法。

我会使用John Wu的答案并使用coalesce运算符,但还有其他可能让你自己得到一个null而不是一个空字符串:

创建extensionmethods类并扩展“string”类:

            public static class ExtensionMethod
            {

                    public static string ConvertEmptyToNull(this string str)
                    {
                            return string.IsNullOrEmpty(str) ? null : str;
                    }

            }
然后使用合并运算符:

var highest = high ?? medium ?? low;
    var highest = HighestPriority.ConvertEmptyToNull() ?? MediumPriority.ConvertEmptyToNull() ?? LowPriority.ConvertEmptyToNull();
但是在您的情况下,我宁愿实现属性的getter,因为您的属性有私有字段

            private string highestPriority;
            public string HighestPriority
            {
                    get
                    {
                            return string.IsNullOrEmpty(highestPriority) ? null : highestPriority;
                    }
                    set
                    {
                            highestPriority = value;
                            HighestSetProperty = Priority.HighestPriority;
                    }
            }
现在,您的聚合链将看起来更干净:

    var highest = HighestPriority ?? MediumPriority ?? LowPriority;

也许你可以使用优先级字典,其中键是优先级。然后只获取第一个NOTNULL值。Linq应该让它简单明了。或者只需使用PriorityString类,将值和优先级作为成员,然后再次使用linq排序并获得第一个非空值。这取决于您是否需要速度或清洁度,因为它们将为您提供不同的解决方案。如果您想在添加或更改属性时担心更改某些内容,请使用反射,如果您不介意在添加属性时更新某些代码,请使用编译后的代码选项,就像您正在做的那样,或者创建一个枚举或列表来映射可能的重复项,然后
OrderBy
优先级
@mjwills谢谢。但是,这是假设我使用priority属性或enum方法。我想问的是,什么样的方法可以为我提供最易维护的代码。因为我正在处理大约6个属性。我是否使用枚举方法?属性方法?另一种方法(如John Wu指出的)。等等。老实说,如果你只有6个属性,我会使用John Wu的方法。如果你有50,我会使用复制链接。谢谢。实际上,我正在尝试为asp.net视图创建显示名称。因此,如果high为null或“”,请使用下一个。例如,如果属性是FirstName和LastName,DisplayName=FirstName??姓。但是,我总共处理了大约6个属性。