我正在记录异常。现在,我可以抛出带有任何参数的异常,并将其提供给log方法。我想在日志消息中显示每个参数的名称,类型和值。类型和值没有问题,但是我无法获取变量的名称。我不想将参数数量加倍,在抛出时为每个参数添加nameof(Value)。
这就是我使用不同参数抛出的方式:
throw new TestException(new object[]{ var0,
var1,
var2,
var3,
var4 });
这是我不想扔给他们的方式:
throw new TestException(new object[]{ var0, nameof(var0)
var1, nameof(var1)
var2, nameof(var2)
var3, nameof(var3)
var4, nameof(var4) });
这些是我对将数据包装到对象中的想法:
public class ArgWrapper
{
public ArgWrapper()
{
}
public string Type { get; set; }
public string Name { get; set; }
public object Value { get; set; }
}
因此,我希望收集具有此类字段的对象,因此我将记录有关每个参数的信息,例如:{类型:“类型”,名称:“名称”,值:“值”} >
答案 0 :(得分:3)
您需要使用GetProperties()
,该方法将返回所有属性
object example = new {si= DateTime.Now, no= "no"}; //object example
var typevar = example.GetType().GetProperties(); //get all te props
//lets loop all the props because it GetProperties() return all props
foreach(var i in typevar){
//if is DateTime well write the name of prop with i.Name
Console.WriteLine("The prop {0} is date time", i.Name);
}
答案 1 :(得分:1)
向ArgWrapper类添加一个方法,该方法可以从参数的表达式中检索所需的信息。像这样:
public class ArgWrapper
{
public static ArgWrapper Create<T>(Expression<Func<T>> expression)
{
T valueAsT = expression.Compile()();
string value = Convert.ToString(valueAsT, CultureInfo.InvariantCulture);
// Get type name
string type = valueAsT?.GetType().FullName ?? "null";
string name = "";
// Get name by traversing memberexpressions from right to left
MemberExpression memberExpression = expression.Body as MemberExpression;
Expression traverseExpression = expression.Body;
while (traverseExpression != null && traverseExpression is MemberExpression)
{
memberExpression = traverseExpression as MemberExpression;
name = memberExpression.Member.Name + "." + name;
traverseExpression = memberExpression.Expression;
}
// If the last memberexpression has no expression, this is a global class name, we want to include
if (traverseExpression == null && memberExpression != null)
{
name = memberExpression.Member.DeclaringType.Name + "." + name;
}
var argWrapper = new ArgWrapper();
argWrapper.Name = name;
argWrapper.Type = type;
argWrapper.Value = value;
return argWrapper;
}
public string Type { get; set; }
public string Name { get; set; }
public object Value { get; set; }
}
如果这是您的异常类
public class TestException : Exception
{
private List<ArgWrapper> parameters = new List<ArgWrapper>();
public IEnumerable<ArgWrapper> Parameters => parameters;
public TestException(params ArgWrapper[] passedParameters)
{
parameters.AddRange(passedParameters);
}
}
然后您可以像这样使用它
private void button1_Click(object sender, EventArgs e)
{
string s = "Hello World";
double pi = Math.PI;
string nullString = null;
var exception = new TestException(
ArgWrapper.Create(() => 42),
ArgWrapper.Create(() => s),
ArgWrapper.Create(() => s.Length),
ArgWrapper.Create(() => pi),
ArgWrapper.Create(() => button1.Text),
ArgWrapper.Create(() => Application.CurrentCulture.Calendar.AlgorithmType),
ArgWrapper.Create(() => DateTime.Now),
ArgWrapper.Create(() => nullString)
);
foreach(var param in exception.Parameters)
{
Console.WriteLine($"{param.Name} - {param.Type} - {param.Value}");
}
}
将产生以下输出:
- System.Int32 - 42 s. - System.String - Hello World s.Length. - System.Int32 - 11 pi. - System.Double - 3.14159265358979 button1.Text. - System.String - button1 Application.CurrentCulture.Calendar.AlgorithmType. - System.Globalization.CalendarAlgorithmType - SolarCalendar DateTime.Now. - System.DateTime - 04/11/2019 18:23:42 nullString. - null -
答案 2 :(得分:-1)
第一部分是正确的。 您需要将这些属性定义为公共属性,并且需要知道包含这些属性的对象!
public Object TestProperty { get; set; } = "test";
private void GetFromName()
{
var properties = this.GetType().GetProperties();
var foundProperty = properties.ToList().Find(property => property.Name == /* nameof(x) string */);
var test = foundProperty.GetValue(/* object containing the property */);
}