同时收集名称和对象

时间:2019-09-18 11:45:02

标签: c#

我正试图组织一个会收集词典的课程。然后,将这些对象打印到控制台。通常,这样一来,您可以查看许多测试用例的最终运行时值,而无需调试每个测试用例,并且还可以避免使用大量手动Console.WriteLines。

This works when I do this but its not quite right

    private Dictionary<string, object> Localvars = new Dictionary<string, object>();

    public void InsertEntry(string objectName, object objectToAdd, string description)
    {
        Localvars.Add(objectName + $": {description}", objectToAdd);
    }

    public static void Main(string[] args)
    {
        var d = new Demo();
        var charizard = "Fire type that looks like a dragon";
        var blastoise = "Water type that resembles a turtle with cannon barrels sticking out of its shell";
        var pikachu = "Electric type that resembles a cute electric rodent";
        d.InsertEntry(nameof(charizard), charizard, "The first one");
        d.InsertEntry(nameof(blastoise), blastoise, "The second one");
        d.InsertEntry(nameof(pikachu), pikachu, "The third one");
        d.PrintVars();
    }

This is closer to how I'd prefer to do it but it throws an error

    private Dictionary<string, object> Localvars = new Dictionary<string, object>();
    public void InsertEntry(object objectToAdd, string description = "")
    {
        Localvars.Add(nameof(objectToAdd) + $": {description}", objectToAdd);
    }        

    public void InsertEntry(params object[] objectToAdd)
    {
        Localvars.Add(nameof(objectToAdd), objectToAdd);
    }

    public static void Main(string[] args)
    {
        var d = new Demo();
        var charizard = "Fire type that looks like a dragon";
        var blastoise = "Water type that resembles a turtle with cannon barrels sticking out of its shell";
        var pikachu = "Electric type that resembles a cute electric rodent";
        // This is ideally how I'd like it to work
        d.InsertEntry(charizard);
        d.InsertEntry(blastoise);
        d.InsertEntry(pikachu);
        // Or this would be even better if the method could take params. I imagine it would be the same solution.
        d.InsertEntry(charizard, pikachu, blastoise);
        d.PrintVars();
    }

现在我知道为什么引发了有问题的错误。它抱怨“已经添加了具有相同键的项” ,因为当我尝试获取 nameof 变量时,该变量将作为参数 objectToAdd传入。这意味着字典中的“密钥”被设置为“ objectToAdd ”,而不是“ 蜥蜴,blastoise,或皮卡丘

很明显,我可以使用 nameof 将其作为字符串传递,并且比我在其他地方看到的内存表达式更具可读性。有什么方法可以将对象作为参数传递给另一种方法,以便可以两者获得名称 内容(如果会员)?我已经回顾了各种想法,例如ref和out关键字,但它们似乎并不是我想要的。

1 个答案:

答案 0 :(得分:3)

“是否可以通过某种方式将对象作为参数传递给另一种方法,以便可以获取成员的名称和内容?”

var charizard = "fire type...";
Foo(() => charizard);

private void Foo<T>(Expression<Func<T>> memberExpression)
{
    var memberName = GetMemberName(memberExpression); // "charizard"
    var expressionValue = memberExpression.Compile().Invoke();  // "fire type..."
}

private string GetMemberName<T>(Expression<Func<T>> memberExpression)
{
    var expressionBody = (MemberExpression)memberExpression.Body;
    return expressionBody.Member.Name;
}

请注意,这仅适用于“成员表达式”,即()=>变量,属性,字段;否则会抛出。据我所知,这是在C#中执行此操作的唯一方法。另请注意,可以将params Expression<Func<T>>[]作为参数(然后Foo(() => charizard, () => pikachu, ...);