2016-08-03 73 views
-1

我希望能够将任何可能的类型作为函数参数传递。传递属性作为函数参数并将其转换为字符串内部的名称

现在,有传递属性的问题,例如。

class Foo 
{ 
    public int Bar { get; set; } 
} 

我能使用: nameof(Foo.Bar) 但我无法做到A(Foo.Bar)凡在将nameof使用。

我想确保字符串是从属性创建的,我希望将属性传递给API并在内部API中执行nameof。

有没有可能通过函数传递属性给nameof?我想隐藏转换的属性到我的班级内的字符串,而不是准备好字符串。如何实现?

编辑:线索是关于:[?]

class B 
{ 
    public Prop {get; set;} 
} 

void foo([?]) 
{ 
    Console.WriteLine(nameof([?])); 
} 

放什么,而不是有一个像控制台输出:道具

+1

为什么不能传递'string'和使用'nameof'主叫网站?你也意识到'nameof(T)'只是给你字面字符串“T”,不管你通过什么类型的对吧? – juharr

+0

对不起,错误的例子,这是我喜欢它的工作。我需要很多字符串的用法,所以这个调用会很糟糕。我想隐藏我的API里面的名字,以确保字符串是从不动产创建的,而不是虚拟数据 – senfen

+0

也许会相应地更新您的问题并解释更多关于您尝试实现的内容? –

回答

1

我想你解释nameof一点点错在这里。

在您的第一个示例中,该方法将始终打印T,并且不依赖于T的类型。 nameof关键字除了用表达式的字符串表示替换给它的表达式之外,什么也不做。例如我们给nameof参数T,他将返回该表达式的字符串表示形式:T

void A<T>(T smth) 
{ 
    Console.Writeline(nameof(T)); // example usage 
} 

一般的nameof用法是提供重构,能够方法/属性/ ...名称的方法。

例如,ArgumentOutOfRangeException的参数名称是参数超出范围

void Test(int value) 
{ 
    if (value < 0) throw new ArgumentOutOfRangeException("value"); 
    // yada yada 
} 

如果我们提供的名称硬编码字符串,如上面的例子中重命名参数时,我们会得到不一致。

为了解决这个问题,我们使用nameof,因为我们提供参数本身而不是硬编码字符串,所以它是重构安全的。

void Test(int value) 
{ 
    if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); 
    // yada yada 
} 
+0

我知道在哪里可以使用nameof,我想知道如何在函数内部使用它来传递参数。我正在做一些反射的东西,我需要比较属性名称。我可以让API的用户在任何地方都会使用nameof(prop),但是我想让这个API在内部确保字符串是从real属性创建的 – senfen

+0

@senfen无法确保用户正在给你正确的输入你应该期望他给你*不正确的输入。只需检查指定的属性是否存在,而不是试图强制提供“正确的”属性名称。 –

+0

好吧,但如果函数调用的nameof的音调不可读,它也看起来很糟糕。那么,有没有可能实现这一目标? – senfen

1

c#编译器在编译时使用'nameof'来查找和替换某些东西,所以它不会如你所期望的那样工作。相反,您需要在运行时使用表达式或反射来获取属性的名称。 这里有一个如何使用表达式做到这一点的例子:

public static string GetName<T>(Expression<Func<T>> expression) 
    { 
     var member = (MemberExpression)expression.Body; 
     return member.Member.Name; 
    } 
    public static string GetName<T>(Expression<Func<T, object>> expression) 
    { 
     var body = expression.Body as MemberExpression; 

     if (body == null) 
     { 
      body = ((UnaryExpression)expression.Body).Operand as MemberExpression; 
     } 

     return body.Member.Name; 
    } 

    public static void PrintName<T>(Expression<Func<T>> expression) 
    { 
     Console.WriteLine(GetName(expression)); 
    } 

    public static void PrintName<T>(Expression<Func<T, object>> expression) 
    { 
     Console.WriteLine(GetName(expression)); 
    } 

像这样来使用:

class B 
{ 
    public Prop {get; set;} 
} 

static void Main(string[] args) 
    { 
     PrintName<B>((b) => b.Prop); 

     //Or 
     var someObject = new B(); 
     PrintName(() => someObject.Prop); 

     Console.ReadLine(); 
    } 
相关问题