是否有可能访问支持字段后面自动实现的属性? [英] Is it possible to access backing fields behind auto-implemented properties?

查看:98
本文介绍了是否有可能访问支持字段后面自动实现的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以使用属性详细的语法:

I know that I can use the verbose syntax for properties:

private string _postalCode;

public string PostalCode
{
    get { return _postalCode; }
    set { _postalCode = value; }
}

或者,我可以使用自动实现的属性。

Or I can use auto-implemented properties.

public string PostalCode { get; set; }

我可以以某种方式访问​​支持字段是自动实现的属性后面? (在这个例子中,这将是_ 邮政code )。

修改:我的问题是不是设计,而是一下,让我们说,这样做的理论能力

Edit: My question is not about design, but rather about, let's say, theoretical ability to do so.

推荐答案

我不知道你,但我已经写了code在其他公司的项目,现在我想知道我是怎么做的东西!因此,它通常是更快地做的答案在网上搜索,它把我带到这里。

I don't know about you, but I've written code in projects in other companies, and now I want to know how I did something! So it's usually quicker to do a web search for the answer, and it brought me here.

不过,我的理由是不同的。我是单元测试,并不在乎什么较真得说,但作为一个单元测试设置的一部分,我想调用某个状态给定对象。但是,国家应该在内部控制。我不希望其他开发商意外地状态,这可能对系统产生深远的影响搞乱。因此,它必须被设置私下!然而,你怎么单元测试类似的东西,而不必调用了(希望)永远不会发生的行为?在这样的情况下,笔者认为,使用反射单元测试是很有用的。

However, my reasons are different. I'm unit testing, and don't care what purists have to say, but as part of a setup for a unit test, I'm trying to invoke a certain state for a given object. But that state should be controlled internally. I don't want some other developer accidentally messing with the state, which could have far reaching effects upon the system. So it must be privately set! Yet how do you unit test something like that without invoking behaviours that (hopefully) will never happen? In such scenarios, I believe that using reflection with unit testing is useful.

另一种方法是公开的事情,我们不想暴露出来,这样我们就可以进行单元测试他们!是的,我已经看到了这个在现实生活环境中,只是想着它仍然让我摇摇头。

The alternative is to expose things we don't want exposed, so we can unit test them! Yes, I've seen this in real life environments, and just thinking about it still makes me shake my head.

所以,我希望在code以下可能是有用的。

So, I'm hoping that the code below might be useful.

这里有两种方法只是关注点分离,真的,同时也可读性帮助。反思是大多数开发商头纺的东西,谁在我的经验,无论是从它避而远之,或避免像瘟疫!

There are two methods here just for separation of concerns, really, and also to aid in readability. Reflection is head-spinning stuff for most developers, who in my experience either shy away from it, or avoid it like the plague!

private string _getBackingFieldName(string propertyName)
{
    return string.Format("<{0}>k__BackingField", propertyName);
}

private FieldInfo _getBackingField(object obj, string propertyName)
{
    return obj.GetType().GetField(_getBackingFieldName(propertyName), BindingFlags.Instance | BindingFlags.NonPublic);
}

我不知道你的工作是什么code约定,但就个人而言,我喜欢的helper方法是私有的,并以小写字母开头。阅读时我没有发现明显不够,所以我喜欢preceding强调了。

I don't know what code conventions you work to, but personally, I like helper methods to be private and begin with a lower case letter. I don't find that obvious enough when reading, so I like the preceding underscore too.

有来头领域的讨论,他们的自动命名。对于单元测试的目的,你很快就会知道pretty,如果它已经改变了还是不行!这不会是灾难性的,以您的真实code要么,只是检验。因此,我们可以做出的命名简单的假设的名字,因为我有以上。你可能不同意,这很好。

There is discussion of backing fields, and their automatic naming. For the purpose of unit tests, you'll know pretty quickly if it has changed or not! It won't be catastrophic to your real code either, just the tests. So we can make simple assumptions about the naming of names—as I have above. You may disagree, and that's fine.

越是困难帮手 __ getBackingField 返回这些反射类型之一,字段信息。我在这里做一个假设,那就是,你后支持字段是一个对象,它是一个实例,而不是静态的。你可以打破伸到参数,如果你想传递的,但海域将肯定是泥泞到谁可能想要的功能,但并不理解普通开发者。

The more difficult helper __getBackingField returns one of those reflection types, FieldInfo. I've made an assumption here too, that the backing field you're after is from an object that's an instance, as opposed to being static. You can break that out into arguments to be passed in if you wish, but the waters will sure be muddier to the average developer who might want the functionality but not the understanding.

关于字段信息的方便的事情 - 是不是他们可以匹配字段信息的对象设置的字段。这是更好地用一个例子说明:

The handy thing about FieldInfos is that they can set fields on objects that match the FieldInfo. This is better explained with an example:

var field = _getBackingField(myObjectToChange, "State");
field.SetValue(myObjectToChange, ObjectState.Active);

在这种情况下,本场名为 ObjectState 枚举类型。名称已被更改,以保护无辜!因此,在第二行,你可以看到,通过访问字段信息返回previously,我可以于的SetValue 方法,你可能会认为应该已经涉及到你的对象,但不!这是反思的性质 - 字段信息分隔它是从哪里来的一个领域,所以你必须告诉它什么实例来一起工作( myObjectToChange ),因此,您希望它具有的价值,在这种情况下, ObjectState.Active

In this case, the field is of an enumeration type called ObjectState. Names have been changed to protect the innocent! So, in the second line, you can see that by accessing the FieldInfo returned previously, I can call upon the SetValue method, which you might think should already relate to your object, but does not! This is the nature of reflection—FieldInfo separates a field from where it came from, so you must tell it what instance to work with (myObjectToChange) and thus, the value you want it to have, in this case, ObjectState.Active.

因此​​,为了使长话短说,面向对象的编程将prevent我们做这样肮脏的东西访问私有字段,更糟的是,改变它们的时候code的开发商并不打算。这是很好的!这就是原因C#是非常宝贵的,并通过开发商的喜爱。

So to make a long story short, object-oriented programming will prevent us from doing such nasty things as accessing private fields, and worse, changing them when the developer of the code did not intend. Which is good! That's one of the reasons C# is so valuable, and liked by developers.

不过,微软给我们的反思,并通过它,我们挥动有力武器。这可能是丑陋的,而且很慢,但在同一时间,它暴露了MSIL(Microsoft中间语言)-IL的内部运作的心底深处短,使我们能够为pretty多休息中的每一个规则书,这是一个很好的例子。

However, Microsoft gave us Reflection, and through it, we wield a mighty weapon. It may be ugly, and very slow, but at the same time, it exposes the innermost depths of the inner workings of MSIL (MicroSoft Intermediate Language)—IL for short—and enables us to pretty much break every rule in the book, this being a good example.

这篇关于是否有可能访问支持字段后面自动实现的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆