我知道我可以拥有一个属性,但这比我想做的更多......并且不够通用。
我想做点什么
class Whotsit
{
private string testProp = "thingy";
public string TestProp
{
get { return testProp; }
set { testProp = value; }
}
}
...
Whotsit whotsit = new Whotsit();
string value = GetName(whotsit.TestProp); //precise syntax up for grabs..
我期望值等于“TestProp”
但我不能为我的生活找到正确的反射方法来编写GetName方法...
编辑:我为什么要这样做?我有一个类来存储从'name','value'表中读取的设置。这由基于反射的通用方法填充。我非常想写反面......
/// <summary>
/// Populates an object from a datatable where the rows have columns called NameField and ValueField.
/// If the property with the 'name' exists, and is not read-only, it is populated from the
/// valueField. Any other columns in the dataTable are ignored. If there is no property called
/// nameField it is ignored. Any properties of the object not found in the data table retain their
/// original values.
/// </summary>
/// <typeparam name="T">Type of the object to be populated.</typeparam>
/// <param name="toBePopulated">The object to be populated</param>
/// <param name="dataTable">'name, 'value' Data table to populate the object from.</param>
/// <param name="nameField">Field name of the 'name' field'.</param>
/// <param name="valueField">Field name of the 'value' field.</param>
/// <param name="options">Setting to control conversions - e.g. nulls as empty strings.</param>
public static void PopulateFromNameValueDataTable<T>
(T toBePopulated, System.Data.DataTable dataTable, string nameField, string valueField, PopulateOptions options)
{
Type type = typeof(T);
bool nullStringsAsEmptyString = options == PopulateOptions.NullStringsAsEmptyString;
foreach (DataRow dataRow in dataTable.Rows)
{
string name = dataRow[nameField].ToString();
System.Reflection.PropertyInfo property = type.GetProperty(name);
object value = dataRow[valueField];
if (property != null)
{
Type propertyType = property.PropertyType;
if (nullStringsAsEmptyString && (propertyType == typeof(String)))
{
value = TypeHelper.EmptyStringIfNull(value);
}
else
{
value = TypeHelper.DefaultIfNull(value, propertyType);
}
property.SetValue(toBePopulated, System.Convert.ChangeType(value, propertyType), null);
}
}
}
进一步编辑:我只是在代码中,有一个Whotsit的实例,我想得到'TestProp'属性的文本字符串。我知道这似乎有点奇怪,我可以使用文字“TestProp” - 或者在我的类的情况下使用数据表函数我将在PropertyInfos的foreach循环中。我只是好奇......
原始代码有字符串常量,我发现它很笨拙。
答案 0 :(得分:6)
不,没有什么可以做的。表达式whotsit.TestProp
将评估该属性。你想要的是神秘的“infoof”运算符:
// I wish...
MemberInfo member = infoof(whotsit.TestProp);
实际上,您只能使用反射来按名称获取属性 - 而不是代码。 (当然,或者获取所有属性。虽然它仍然无法帮助您处理样本。)
一种替代方法是使用表达式树:
Expression<Func<string>> = () => whotsit.TestProp;
然后检查表达式树以获取属性。
如果这些都没有帮助,或许你可以告诉我们更多你想要这个功能的原因吗?
答案 1 :(得分:3)
有可能(没有反思)但只能使用最新的C#3.0
快速&amp;非常非常脏
class Program
{
static void Main()
{
string propertyName = GetName(() => AppDomain.CurrentDomain);
Console.WriteLine(propertyName); // prints "CurrentDomain"
Console.ReadLine();
}
public static string GetName(Expression<Func<object>> property)
{
return property.Body.ToString().Split('.').Last();
}
}
更新:我刚刚意识到Jon Skeet(有人感到惊讶吗?:)已经涵盖了这种可能性,但我会在这里保留我的答案以防万一有人对某些人感兴趣例子开始。
答案 2 :(得分:0)
你想做的事是不可能的。使用反射你可以:
调用时,GetName方法会传递一个字符串。 GetMethod将了解字符串,但不保留源属性元数据。
出于兴趣,你为什么要这样做?
答案 3 :(得分:0)
我不认为这是可能的,唯一的方法是迭代属性:
class TestClass
{
private string _field;
public string MyProperty
{
get { return _field; }
}
}
class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass();
PropertyInfo[] info = test.GetType().GetProperties();
foreach(PropertyInfo i in info)
Console.WriteLine(i.Name);
Console.Read();
}
}
答案 4 :(得分:0)
Kpollack,你在之前的评论中说过:
仍然不会让我能够从它的实例中获取属性的名称。
这让我相信你以某种方式引用了一个属性。你是怎么得到这个参考的?它的类型是什么?你能提供一个代码示例吗?如果它是PropertyInfo对象,那么您已经拥有了所需的东西;由于情况似乎并非如此,我们正在处理其他问题,而且我非常有兴趣了解您做必须使用的内容。
P.S。请原谅我似乎迟钝:它早,我没有足够的咖啡,而且我没有在我面前使用我的IDE。 : - /
答案 5 :(得分:0)
仅供参考,我试图将其序列化,看看是否偶然包含了属性名称,但没有运气。
以下非工作代码:
Whotsit w = new Whotsit();
XmlSerializer xs = new XmlSerializer(w.TestProp.GetType());
TextWriter sw = new StreamWriter(@"c:\TestProp.xml");
xs.Serialize(sw, w.TestProp);
sw.Close();
答案 6 :(得分:-1)
GetProperties on the Type class将为您提供该类型的属性列表。
Type t = whotsit.GetType();
PropertyInfo[] pis = t.GetProperties();