根据传递给方法的值选择要使用的属性

时间:2017-09-08 18:13:40

标签: c# linq

我想从列表中选择一天,并根据它的日期返回它的值。我需要比较中的属性以某种方式动态

  void Check(string Day)
      {
          //This string holds the three day property prefix
          string subStrDay = Day.Substring(0, 3).ToLower().ToString();

          if (dayList.Exists(y => y.mon.Contains("True" + " " + Day + " " + "True")))
          {
              startWork(Day, userID, true);
          }
          else
          {
              startWork(Day, userID, false);
          }
     }

基本上我需要" y.mon"能够成为" y.tue" " y.wed'等等 不,我不能只将subStrDay变量放在那里。感谢

3 个答案:

答案 0 :(得分:3)

选项1.正是您要求的

将这个方便的扩展方法添加到您的库中:

public static T Peek<T>(this object o, string propertyName)
{
    return (T)o.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public).GetValue(o);
}

要根据动态字符串获取日期值,请调用

var Day = "mon";
var s = y.Peek<string>(Day);

选项#2。使用带有动态字符串

的属性修改类

这是一种更典型的设计,无需使用反射。

你不能说出y是什么类型,但我认为它是类似的类:

class ClassY
{
    public string mon { get; set; }
    public string tue { get; set; }
    public string wed { get; set; }
    public string thu { get; set; }
    public string fri { get; set; }
    public string sat { get; set; }
    public string sun { get; set; }
}

相反,请考虑组建一个新类DayCollection,仅用于存储和检索日期。所以:

class DayCollection
{
    private Dictionary<string, string> _dayList = new Dictionary<string, string>();
    public string this [string day]
    {
        get { return _dayList[day;}
        set { _dayList[day] = value; }
    }
}

现在你的&#34; Y班&#34;更短:

class ClassY
{
    public DayCollection Days  = new DayCollection();
}

然后代替

if (dayList.Exists(y => y.mon.Contains("True" + " " + Day + " " + "True"))

使用它:

if (dayList.Exists(y => y.Days[Day].Contains("True" + Day + " " + "true"))

如果您打算访问由动态字符串确定的日期值,这是一个更好的设计。

如果你坚持每天的财产

如果您坚持每天都拥有一处房产,您仍然可以将其添加到顶部:

class DayCollection
{
    private Dictionary<string, string> _dayList = new Dictionary<string, string>();
    public string mon
    {
        get { return this["mon"]; }
        set { this["mon"] = value; }
    }
    public string mon
    {
        get { return this["mon"]; }
        set { this["mon"] = value; }
    }
    public string tue
    {
        get { return this["tue"]; }
        set { this["tue"] = value; }
    }
    //Etc....

    public string this[string day]
    {
        get { return _dayList[day;}
        set { _dayList[day] = value; }
    }
}

因此,以下两个做同样的事情:

var s1 = y.Days["mon"];
var s2 = y.Days.mon;
Assert.AreEqual(s1, s2);

现在使用通用词典

一旦了解了上述方法的工作原理,就可以通过继承来减少工作量。

您可能会注意到我们的DayCollection看起来很像字典。事实上,你可以写出这样的全部内容:

class DayCollection : Dictionary<string, string>
{
    //Nothing
}

如果你想要每天的财产只是添加到班级:

class DayCollection : Dictionary<string, string>
{
    public string mon
    {
        get { return this["mon"]; }
        set { this["mon"] = value; }
    }
    //Etc....
}

使这非常快速且易于实施。

答案 1 :(得分:0)

如果你真的想要按照你当前的路径,你可以使dayList成为一个字典,每个键都是&#34; mon&#34;,&#34; tue&#34;等等。然后有值应该是它实际需要的对应字符串。

然后,您可以将代码更改为dayList.Exists(y => y[Day].Contains("True" + " " + Day + " " + "True")

答案 2 :(得分:0)

它有点沉重,但如果我理解你并且你没有选择修改你的日程,你可以建立一个表达式:

    private static Expression<Func<Y,List<string>>> GetExrpession(string subStrDay)
    {
        var parameter = Expression.Parameter(typeof(Y), "y");
        var propertyExpression = Expression.Property(parameter, subStrDay);
        return Expression.Lambda<Func<Y,List<string>>>(propertyExpression, parameter);
    }

并使用它:

static void Check(string Day)
{
    //This string holds the three day property prefix
    string subStrDay = Day.Substring(0, 3).ToLower().ToString();

    var exp = GetExrpession(subStrDay).Compile();

    startWork(Day, UserID, dayList.Exists(y => exp(y).Contains("True" + " " + Day + " " + "True")));

}