下午好,
我不确定如何表达我的问题,所以请原谅任何不相关的内容,如果我遗漏了任何重要的内容,请告诉我!我对lambdas,regex和linq也缺乏经验,所以要指出我做得不好/可能做得更好的事情。
我的问题是:我可以获得一个类的引用,我只知道一个属性吗?具体来说,在下面的代码片段中,我想将propertyValues[0]
中的索引0更改为存储在同一个类中的变量。是否有类似this
的内容访问父项?
有关更多背景信息,我已粘贴相关修剪后的代码。
return Regex.Replace ( originalString, "{(.*?)}", match =>
User.user.properties.First( property =>
property.id == match.ToString ().Substring ( 1, match.ToString ().Length - 2 ))
.propertyValues[0].adjectives[0]);
public class Property
{
public string id;
public List<Value> propertyValues = new List<Value> ();
public sbyte propertyIndex;
}
感谢您花时间阅读本文!
感谢您的反馈,Philip Stuyck我会尝试更好地解释。
我正在寻找一种获取对属性的父类的引用的方法,或者是一种在lambda表达式中创建局部变量的方法。为了说明,我有以下类和返回方法。
属性类,
public class Property
{
public string id;
public List<Value> propertyValues = new List<Value> ();
public sbyte propertyIndex;
}
用户类,
public class User
{
public static User user = new User ();
internal List<Property> properties = new List<Property> ();
}
GetVariable方法,
public static class GetVariable
{
public static string FromUser ( string originalString )
{
return Regex.Replace ( originalString, "{(.*?)}", match => User.user.properties.First ( property => property.id == match.ToString ().Substring ( 1, match.ToString ().Length - 2 )).propertyValues[0].adjectives[0]);
}
}
GetVariable.FromUser
方法应该返回一个新字符串,该字符串用User.user.properties
中的字符串替换括号中包含的子字符串的每个实例。因此,它可以传递“This is a {Example}。”,并返回“This is a Demo”(如果User类具有id为example的属性,并且值为Demo)。
我的问题是关联GetVariable方法,更具体地说,是最后一部分:propertyValues[0]
。我希望索引(当前为0)是Property类的变量,User.user.properties.First
委托找到它。
因此,理想情况下,它会像User.user.properties.First ( property => property.id == match.ToString ()).propertyValues[property.propertyIndex]
一样简单,但我无法访问括号外的属性。
我希望这有助于解释它,虽然我觉得它仍然太复杂了。如果我能想出一个更好的方式来表达我的问题,我会这样做。此外,我很乐意通过评论澄清任何内容。
答案 0 :(得分:1)
简而言之,没有。如果您有对象的引用,则可以使用Reflection从中获取可能未知的属性,但在拥有属性时无法找到任意对象。这是有道理的,因为如果你有一些名为Id
的属性,它可能是任何对象的属性,那么C#如何尝试开始将其解析回Type - 更不用说该类型的特定实例。 / p>
如果你知道你有什么实例,你可以像这样使用反射:
var myProperty = myInstance.GetType().GetProperty("Id");
myProperty.SetMethod.Invoke(myInstance, new object[] {42});
//this will set the given property on the given
//instance with the given value (42 in this example)
//GetMethod is also there
//depending on what you need to do with it
但是我应该澄清一下,上面的反射仅适用于 Properties ,在你的例子中你有字段,所以你需要得到的FieldInfo与属性有点不同。
但是在上面的示例中似乎不清楚,看起来你有一个实例并知道类型,所以为什么你不能使用:
Regex.Replace (
originalString,
"{(.*?)}",
match =>
User.user.properties.First( property =>
property.id == match.ToString().Substring( 1,
match.ToString().Length - 2))
.propertyValues[(int)property.propertyIndex]
.adjectives[0]);
除非我不明白你的要求,否则看起来会有效吗?
<强>更新强>
好的,我还在努力,因为你的最终目标并不是非常明确,但看起来你想要的是将你的匹配上下文包装在一个方法体中,这样你就可以访问了匹配在失去范围之前多次找到的属性。
像这样的东西,我认为你在找什么:
return Regex.Replace (
originalString,
"{(.*?)}",
match =>
{
var matchStr = match.ToString()
var formattedMatch = matchStr.Substring(1, matchStr.Length - 2);
var prop = User.user.properties.First(
property => property.id == formattedMatch);
return prop.propertyValues[(int)prop.propertyIndex].adjectives[0];
}
<强> TL; DR 强>
我应该提一下,因为你说你是Linq和lambdas的新手,基本上Expression<T>
或LambdaExpression
是Func<TArgs..>
,它是在执行时而不是在编译时编译的,所以当你写c => c.Id == 42
时你正在做的是创建一个如下所示的方法:
internal static int _closureVariable = 42;
public static bool checkName(Property prop)
{
return prop.Id == _closureVariable;
}
关于它如何处理和生成有一点涉及,但最终结果是相似的。
所以在我使用方法体的示例中,我只是创建一个具有如下签名的更复杂的方法:
public static string matchRegex(Match match);
然后所有工作都在该方法签名中进行。重要的是要记住,当表达式上没有声明方法体时,return关键字是隐式的(即c => c.Name == "some name"
隐式返回true
)所以如果你有一个方法体({{ 1}})你需要显式声明返回,否则它将返回void。 (即c => { ... }
)。