I have an object named currHotel. It holds values like:
address
bigImageUrl
Category
Chain
City
and so on
This object contains another object inside it, with different values, named - Ben.Hotel.HotelFinder.BC_Hotel:
How can I access the object Ben.Hotel.HotelFinder.BC_Hotel that's inside currHotel?
It doesn't appear in it, and I need some values from it:
As I understand it, the values that you want to access are on your base class? In that case, check the access modifiers on those fields/properties/methods, and make sure that they are exposed in the way you want.
The simplest (and least safe!) approach is to make everything public but depending on where you are trying to read those fields/properties/methods you may be able to get away with protected (accessible in derived classes) or internal (accessible anywhere in the same assembly) instead.
Edit:
Also remember that there is not really a BC_Hotel object "inside" current, but rather current is a BC_Hotel (since its class is derived from it), so all the fields on that base class are available directly on current, depending on access (as I said above).
your currHotel is an instance of type Ben.Hotel.HotelFinder.BC_Hotel.
From the screenshot, the currHotel doesn't have another property of type Ben.Hotel.HotelFinder.BC_Hotel.
Related
Probably I need a design pattern here: I have a factory that produces instances by the type. I want the user to be able to choose the type, so I need a caption for the type, then a list of the the common ancestor of the types.
Now, I'd like to enumerate the list, and print the captions. (No can do that, the static caption properties are inaccessible from the ancestor)
Then, I'd like to print the caption of an instance. Unable to do that, since the class properties are inaccessible from an instance.
If I use a dictionary, that connects the type and the caption, captions are again, inaccessible from the instance, nor the type, etc.
I've been using Delphi for 20 years, and used virtual constructors and virtual class properties every day. I kind of like C#, but after years, I still don't have comfy solution for such things. (Thanks for the help in advance)
Using System.Reflection you can enumerate all types of an assembly, check if they derive from a given base type or implement a certain interface.
You can also access non public fields or properties (static or instance).
So may be this is the way to go.
If the class hierarchy is you own code, you also could/should simply redesign it a little to get access to the members that are now restricted..
The title is a bit of a mouthful, but it's easier to see in code:
public struct MyStruct {
public bool HasAttribute(Attribute attribute) {
//is there any way to know?
return ??????;
}
}
public class MyClass {
[SomeAttribute]
MyStruct child;
public MyClass() {}
}
I already know how to find the attributes on MyClass.child by getting the property info for each of its properties and then calling GetCustomAttributes, but this only works if I know that the struct instance corresponds to MyClass.child. What I'd like to do here is to figure out if a particular instance of a struct has attributes attached to it, without knowing what class contains the particular instance.
It would make sense to me if you couldn't do this for reference types because the instance could be referenced from multiple places, but shouldn't the set of attributes always be well-defined for value types?
My use case is making a library where the behavior of certain objects can be modified slightly by attaching custom attributes. If there's a more idiomatic way to approach this then I'm open to suggestions. I'm also willing to go into an unsafe context if that allows for a solution.
Sorry, but that's not possible. [SomeAttribute] is attached to the field of MyClass, and is completely unrelated to MyStruct.
There's no way to get the container of a struct for a couple of reasons:
It could simply be a local variable or a temporary, which means the struct could either live on the stack or in a CPU register. So, no there's no containing class there.
It could be contained in another struct, which would be subject to the same issue.
If it's contained in a class, you'd have to retrieve the container type using only the struct's address. And that would involve very nasty code, if possible at all.
Just imagine: The address of such a struct would be the address of its containing class plus an offset. You'd have to somehow find the address of the container's vtable (assuming you could infer what looks like a vtable just from a memory address). This would be totally hazardous/unsafe and unreliable, you'd run the risk of getting access violations all the time since you'd have to dereference unknown addresses. There's just no way to get something reliable out of it.
Oh, and you'd also have to do this while the GC could potentially move your container object around, without the possibility of pinning it since you don't know its address in the first place.
A saner approach would be to use the CLR debugging API, but at this point I'll assume you just don't want to summon Cthulhu.
I'm sure there are many other ways to achieve what you want there, but I can't be more specific without more details. Right now, I'd suggest initializing your struct explicitly, with additional parameters:
public class MyClass {
MyStruct child = new MyStruct(doThatSpecialThingie: true);
}
I have a class, and I am doing some nifty things with reflection.
Now I have a need to add some meta data associated to a particular field when I am assigning a value to the field of a class using reflection (I don't know what the class will be).
I would like to do this without the clients to my implementation knowing (having to do anything special of their own).
Having a designated "meta" field or object within the class would work, but doesn't feel very elegant since it requires the child class to do something to be "compatible". I would like to dynamically attach this meta information to the existing class, but still allow it to be treated like the same class be the rest of the application. I would like to be able to recover this meta information later.
Class gets passed in
Values get assigned (mapped) via Reflection with
Meta information attached
Class returned
*This process should have no side effects in regard normal operations and the object type of the class. To the general application the class should be the same before and after.
Application does "normal" work with the class (assign values, get values, validate information ,etc.)
Class gets passed back in later
Use the values along with meta information to do something
Broken down to the simplest terms, I am basically looking for a way to "Piggy-back" extra information on any arbitrary class instance without special compile-time modification.
I realize this is an odd problem with some odd constraints, but can it be done?
This applies if you need the extra state per type and not instance
Your best bet is to use a custom attribute against the field.
1) So create the attribute:
[AttributeUsage(AttributeTargets.Field)]
public class MyCustomAttribute : Attribute
{
}
2) Decorate the field:
class MyClass
{
[MyCustomAttribute]
private int _myField;
....
}
3) And then in your reflection:
if(fieldInfo.GetCustomAttributes(typeof(MyCustomAttribute), true).Length>0)
{
...
}
If it has got to be in the instance
If data is to be part of the instance then
either instance needs to allow for its storage
state needs to be stored on a separate class like a dictionary
Second approach is the one first coming to mind and straightforward to do. On the first note, one can
Define state as a separate property that can hold info. This is the one you have suggested and you are not happy with.
Inherit from a base class which provides the extra functionality
Create a generic type, e.g. Metadata<T> which will provide such functionality to all types
I tend to like the third which can encapsulate reflecting the type T and creating necessary placeholders for storing extra state. Main problem with this is you cannot pass the type to methods as a parameter. Which seems that the second solution is the most practical.
I'd be inclined to create a dictionary with the object instances as the keys and the metadata as the values. You'd probably need to be careful to ensure that equality is determined with ReferenceEquals() rather than Equals(). You might also need a compound key comprising the object and the relevant PropertyInfo.
This approach also wouldn't work if the metadata needs to follow the object into some context where the metadata dictionary is not available.
This question already has answers here:
What is the difference between a field and a property?
(33 answers)
Closed 8 years ago.
Edit, as per these comments:
Do you mean "Property" vs "Field"?
public String S1; vs public String S2
{ get; set; } – dana
Exactly dana, i mean the same. – Asad
Asad: you really need to try to use
some other term to describe what you
mean so that we can better understand
your question. C# does not have global
variables. The fields you can define
in C# are not global - they are
members of the class type. – dthorpe
Hi fellas,
Need your expert views over the difference between Field and Property. As in my project, I have used certain global variables which later on i changed to 'Properties' . My manager is asking what is the benefit of using Properties of variables instead of Fields.
Although I have replied him that Property provides a kind of secure/safe/indirect access to Field instead of modifying them directly if they are declared public or protected. But Please provide me with some more convincing arguments.
Thanks and Regards
#Asad:
You should get your terminology right: Fields are not Global Variables, C# does not have global variables (as a few commenters mentioned: you can simulate global variables, but you should not do that).
The main advantage is that you can attach all sorts of functionality to a property such as validation, synchronization etc. You can't do that for a class field. For example, a field can throw BCL exceptions on assignment but it can't throw an exception that make sense with logic in your problem domain.
Also imagine trying to protect a field for thread synchronization. You have to write extra code in all the places in your code where the field is accessed. To do that with a property you can simply wrap the getter and setter with a lock in one place. (But beware! The ease of using lock in property getters and setters can give you a false sense of security if you're working with mutable types. See the accepted answer in this post.)
Now, you might think that validation and synchronization are not important to you for this particular value, and they may never be for this particular instance. But by using properties instead of direct field access is making your application much more maintainable in the future. (Suppose the value of an integer field suddenly needs to come from a source different from the original implementation and it needs to be converted from a string to an int. If you use properties to wrap the field then you make the change in one place and all the client code that uses that property does not need to change at all!)
Also, for managing information shared across many classes (global) take a look at the singleton pattern. But beware! Even though it looks neat and clean you can still get into trouble with it. Though if you really need global data you should use properties contained in a singleton. If nothing else, it's a good organization strategy.
To avoid issues with singletons or "global" data take a look at dependency injection as a much better alternative.
C# syntax doesn't have a "global variable" declaration. It has properties and fields, and static properties and fields.
If by "global variable" you mean a static field or static property, that is different from a property or field in that the static field or property is not stored in the object instance data, it is stored in global memory. The value assigned to a static field or property is accessible to all instances of that class, and all instances see the same value. A static field is the closest thing C# has to the notion of "global variable" found in other programming languages.
A non-static property or field stores its data in the object instance data, so each instance of the object has its own local copy. Modifying object1.A property will not affect the value of object2.A property.
Have a look at Properties (C# Programming Guide)
A property is a member that provides a
flexible mechanism to read, write, or
compute the value of a private field.
Properties can be used as if they are
public data members, but they are
actually special methods called
accessors. This enables data to be
accessed easily and still helps
promote the safety and flexibility of
methods.
Properties enable a class to expose a
public way of getting and setting
values, while hiding implementation
or verification code.
A get property accessor is used to
return the property value, and a set
accessor is used to assign a new
value. These accessors can have
different access levels.
Properties that do not implement a
set accessor are read only.
I prefer properties because then when I use them in code I know exactly which class was used to call them (ex. class.property = value). Public class variables can become a real pain and waste of time when you are trying to figure out where they came from during debugging.
In most of the cases we usually creates a private variable and its corresponding public properties and uses them for performing our functionalities.
Everyone has different approach like some people uses properties every where and some uses private variables within a same class as they are private and opens it to be used by external environment by using properties.
Suppose I takes a scenario say insertion in a database.
I creates some parameters that need to be initialized.
I creates 10 private variables and their corresp public properties
which are given as
private string name;
public string Name
{
get{return name;}
set{name=value;}
}
and so on. In these cases mentioned above, what should be used internal variables or properties.
And in those cases like
public string Name
{
get{return name;}
set{name=value>5?5:0;} //or any action can be done. this is just an eg.
}
In such cases what should be done.
What is the conclusion
I actually meant to ask this.
Should we use variables within that class or not or should we use properties everywhere within same class as well.
If you use auto-implemented properties, then the field will be hidden, so you are forced to use the property, even in the class where the property is defined. Auto-implemented properties are a good idea, unless you need to add some logic to the getter/setter.
If the only use for the private variable is as a storage container, you might use:
public string Name {get; set;}
IMHO one should never make variables public - always use properties so you can add constraints or change behaviours later on whitout changing the interface.
Made things more readable:
I expose my data always through properties.
If I do not need additional logic (e.g. validation) I use implicit properties. This way there is no backing field and I cannot access it by accident. If I need to add some additional logic I can easily change the implicit property to a "traditional" one. As I use the property everywhere I do not have to worry that my extra logic is not called.
If I need something extra (like validation) then I have a private backing field, but I access this field only in the property body (get/set accessors). Again I do not need to worry if I change something in the property: My code will always use the same logic.
The only reason for not calling the property in my opinion would be if for some reason I really do not want any additional logic to be called, but this seems a dangerous thing so I rather avoid it...
I never expose public variables. Why? Because I can't lay constraints on them, whereas I can when I'm using properties. I can first check the value if it meets my constraints (e.g. an email address) and then I save it. Otherwise I throw an Exception.
You should never expose public variables without a very good reason. It is tough to say never, because if you trying to interop with comm type components you might be required too.
Anything publicly exposed should be a property. Why is that?
The reason is if you need to change the source of the value, or add some business logic checking if it is a public member you are going to require anything using the code to change. If it is a property you can change the internal logic and not require anybody using it to change the code.
I personally use properties and only create members variables when I want a property to do more than getting or setting (since this is easy with C# 3.0 with shortcut properties).
If I want to keep a property from being publicly exposed I make it as private, and only expose it when I have too.
We require explicit private variables in some situation like validation before set.Sometime we also need to conversion of input, for instance , formatting the input.