C# 通过引用传递属性
无论如何,是否可以通过引用传递对象的属性?我知道我可以传递整个对象,但我想指定对象的属性来设置并检查它的类型,以便我知道如何解析。我是否应该采取另一种方法(无论如何我都无法更改原始对象)?
public class Foo{
public Foo(){}
public int Age { get; set; }
}
private void setFromQueryString(object aProperty, String queryString, HttpContext context)
{
//here I want to handle pulling the values out of
//the query string and parsing them or setting them
//to null or empty string...
String valueString = context.Request.QueryString[queryString].ToString();
//I need to check the type of the property that I am setting.
//this is null so I can't check it's type
Type t = aProperty.GetType();
}
private void callingMethod(HttpContext context)
{
Foo myFoo = new Foo();
setFromQueryString(myFoo.Age, "inputAge", context);
}
Is there anyway to pass the property of an Object by reference? I know I can pass the whole object but I want to specify a property of the object to set and check it's type so I know how to parse. Should I maybe take another approach (I cannot change the original object in anyway)?
public class Foo{
public Foo(){}
public int Age { get; set; }
}
private void setFromQueryString(object aProperty, String queryString, HttpContext context)
{
//here I want to handle pulling the values out of
//the query string and parsing them or setting them
//to null or empty string...
String valueString = context.Request.QueryString[queryString].ToString();
//I need to check the type of the property that I am setting.
//this is null so I can't check it's type
Type t = aProperty.GetType();
}
private void callingMethod(HttpContext context)
{
Foo myFoo = new Foo();
setFromQueryString(myFoo.Age, "inputAge", context);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以使用 lambda 表达式调用该函数:
您可以这样调用它:
编辑:如果您确实想要类型推断:
You can call the function with a lambda expression:
You would call it like this:
EDIT: If you really want type inference:
正如其他人所指出的,您可以使用委托来执行此操作,使用多种指定委托的方法之一。但是,如果您打算定期执行此操作,则应该考虑创建一个包装器类型,用于通过引用传递属性来包装所需的委托,它可能会创建一个更好的 API。
例如:
这样您就可以传递对属性的引用并通过设置引用值来修改它。
As others have pointed out, you can do this using delegates, using one of the many ways to specify delegates. However, if you intend to do this regularly, you should consider creating a wrapper type for passing properties by reference that wraps the delegates required, it may create a nicer API.
For example:
That way you can pass around a reference to your property and modify it by setting the reference value.
不,没有办法直接通过引用传递属性。 Visual Basic 通过将属性值放入临时变量中,然后通过引用传递并在返回时重新分配,在该语言中提供此支持。
在 C# 中,您只能通过传递
Func
来获取属性值,并传递Action
来设置值(使用闭包)来近似此行为,其中T
是属性的类型。No, there is no way to directly pass the property by reference. Visual Basic offers this support in the language by putting the value of the property into a temp variable, and then that is passed by reference and reassigned upon return.
In C#, you can only approximate this behavior by passing a
Func<T>
to get the property value, and anAction<T>
for setting the value (using closures), whereT
is the type of the property.您可以使用相应的方法和委托包装属性并传递委托。
You could wrap the property with a corresponding methods and delegates and pass the delegates.
使用 lambda 传递函数可能是最优雅的,但如果您只是想要一个简单的解决方案来解决您的问题
Passing function with lambda is probably most elegant, but if you just want a simple solution to your problem
为什么不使用泛型并返回对象?
不太清楚为什么你如此热衷于推理,但考虑到你是这样,你可以这样做
Why not use generics and return the object?
Not quite sure why you're so set on inference, but given that you are, you could do this
你为什么把事情搞得这么复杂?您在编译时就知道属性的类型,只需用一行代码即可轻松完成:
如果您需要检查类型,只需添加一个包装 int.TryParse() 并返回无害结果的小函数(例如0) 如果您在查询字符串值中得到“pdq”而不是数字。
Why are you making it so complicated? You know the type of the property at compile time, just do it the easy way with one line of code:
If you need to check the type, just add a little function that wraps int.TryParse() and returns an innocuous result (e.g. 0) if you get "pdq" in the querystring value instead of a number.
这里有一个完全不同的解决方案:
创建从 System.Web.UI.Page 派生的类,并将 QueryString 参数作为属性。另外,使用实用程序函数(请参阅下面的 ConvertType),您无需执行太多操作即可从 QueryString 中获取数据。最后,在这些派生类中,定义一个静态内部类,它保存作为 QueryString 参数名称的常量,这样您就不需要在任何地方引用任何魔术值。
我通常为我的项目定义一个基页面类,这使得它成为一个方便的地方来执行所有页面上发生的常见操作以及一些实用函数:
然后,在常规页面中,在后面的代码中,它现在看起来像这样:
它使类背后的代码非常干净(如您所见),并且易于维护,因为所有繁重的工作都是由两个函数(GetQueryStringValue 和 ChangeType)完成的,这两个函数在每个函数中都重用页面类的所有内容都是类型安全的(您会在 GetQueryStringValue 中注意到,您可以指定如果值无法转换或仅使用返回默认值,函数是否抛出异常;两者在不同时间都适用,具体取决于你的应用程序)。
此外,您甚至可以轻松编写 VS 插件或 CodeSmith 脚本来轻松生成派生页面类。而且没有一堆代表和东西被传递,我发现新开发人员很难理解这一点。
Here's a totally different solution for you:
Create classes derived from System.Web.UI.Page that have the QueryString parameters as properties. Also, using a utility function (see ConvertType, below), you don't need to do too much to get the data out of the QueryString. Lastly, inside those derived classes, define a static inner class that holds constants that are the names of the QueryString parameters so that you don't need to reference any magic values anywhere.
I usually define a base page class for my project, which makes it a convenient place to do common things that happen on all pages, as well as a few utility functions:
Then, in your regular page, in the code behind, it now looks like this:
It makes the code behind classes very clean (as you can see), and it's easily maintainable because all the heavy-lifting is done by two functions (GetQueryStringValue and ChangeType) that are reused in each of the page classes, and everything is type-safe (you'll notice in GetQueryStringValue that you can specify whether the function throws if the value can't be converted or just uses returns default value; both are appropriate at different times, depending on your app).
Furthermore, you can even easily write a VS plugin or CodeSmith script to generate the derived page class quite easily. And there aren't a bunch of delegates and stuff being passed around, which I find new developers have a hard time understanding.