Passing "this" as an argument - C# - c#

I'm currently playing about with some XNA stuff learning to program AI. Anyway, here's my situation: Class A has a function which takes a reference to an instance of class B, does some stuff to to it, and returns it. Class B contains an instance of Class A, and then calls the function from it.
Example in code:
Class A
{
B classB;
public A()
{
classB = new B();
}
public void Act()
{
this = B.Do(ref this);
}
}
Class B
{
public A Do(ref A classA)
{
//Manipulate
return classA;
}
}
I've tried passing a memberwise clone .. but that didn't work, obviously, because "this" is read-only. I've no idea with this. I'm really stuck. Does anybody have any ideas? I'd ideally like to avoid having to pass every single variable in the object as a separate argument, really.
Andy.

Classes are reference types, so doing
Class B
{
public void Do(A classA)
{
//Manipulate
}
}
should manipulate the object classA references. Then in A,
Class A
{
B classB;
public A()
{
classB = new B();
}
public void Act()
{
B.Do(this);
}
}
Note: "This does have the side effect that the reference of A that you pass cannot be set to null (it will only set the local variable to null)" - JulianR

Your B.Do() method does it (modifying an A) double by using the ref and a return. Neither is needed to modify classA. And because you target this it won't work anyway. You never assign to this, it makes no sense.
So the Simple answer is
class B
{
void Do(A anA) { anA.PublicProp = 1; }
}
But the circular referencing does make it a dubious design.

Is there something specific in //Manipulate that requires you to pass a class reference as ref? And why are you also returning classA as well - that seems to be redundent if you are using ref to begin with.

just remove the ref keyword. you only need ref if you want to change the argument into something else, if you just want to manipulate it, don't use the ref.
I think it would be bad (tricky to understand) if the language allowed you to change this into that, so it disallows what you've tried.

you cannot use "ref" with "this".
Why do you need the parameter to be passed by reference ?
You only need a "ref" parameter if your function must change which object the caller is refering to. If all you need is to manipulate and/or change the fields of the parameter then you do not need a ref parameter.

For more clarity, the whole thing is for behaviours for simple AI (EG chase, guard, evade etc). I'm wanting to pass the entire AI entity to the behaviours so that I can keep the behaviours separate for all entities (Sort of like a single style sheet for multiple web pages). The reason I want to pass the whole object is that some behaviours need certain parts of the object and some don't.
As for why I'm returning .. I don't quite know how I came to that decision. I'll remove it

Thank you very much, Derek E!
I just tested what you said, and it worked fine.
My problem, I think, is that I was thinking that when I passed the argument it made a clone of it and manipulated that instead, like (I think ..) it does in PHP or VB (can't remember which of those I was told it does it in)

Objects are always passed by reference and not by value. That is why we call classes in C# as reference types. Be careful if you are using structures instead since they are value types. A copy of the structure will be passed rather than the original. If you wish to pass the original then you must add the ref keyword. ref is only useful with objects if you wish to replace a reference to one object with a reference to another object.

Related

Accessing instance-level custom attributes in c#

Imagine I have the following code:
class A
{
[UsefulAttribute("foo")]
B var1;
[UsefulAttribute("bar")]
B var2;
...
}
class B
{
public string WriteSomethingUseful()
{
?????
}
}
My question is, what code do it need to put in the ????? such that, when I call var1.WriteSomethingUseful I get an output of foo, and when I call var2.WriteSomethingUseful I get an output of bar?
I've got a feeling this is quite a straightforward question, I think my main issue is that I have worked myself into a state of confusion by thinking about it for too long!!!
Seriously, I have defined UsefulAttribute and realise that part of the code must be a GetCustomAttributes(typeof(UsefulAttribute)...) call. Where I'm getting confused is how to pull these values out on the actual instance, rather than at the type level.
Many thanks,
Pete
This isn't possible. For starters, what if multiple different instances of A have references to the same B? Or what if the same instance of B is referenced by both var1 and var2?
When you set the attribute on the field, you are attaching that attribute to the type of class A, not the instance of class B stored in the field var1.
The normal way to go about this is to store the data as a property of B, set it either via a property setter or a constructor parameter, and then access the property from the WriteSomethingUseful method.
Since your WriteSomethingUseful() method is within the type B, but your attributes are declared within type A you will not be able to access them based on an instance - you simply don't have a reference to A.
The current B instance might not be related to A at all, and without being able to retrieve "the type of the class instance (if any) that contains the current B instance" - which is not possible in C# - there is no general way to do this.

Passing form object by reference

Hey! I've made a little boiler system that's controlled entirely by a form. The form components, however, call functions in a class for the boiler, radiators and so on.
I've got a little main class to that instantiates all of the classes but I'm struggling to figure out how to pass the form object to those classes so that they can access the form's components.
I guess I should be using mutator methods in each class to store the form object? How would I do this that's syntactically correct?
Thank you! ;o)
Just pass the form to each class. Store it in a private variable so the class can use it later. It is passed by reference by default.
class Boiler {
private Form parentForm;
public Boiler(Form f) {
parentForm = f;
}
}
When you pass a reference type to a method, C# (by default) will pass a copy of the reference to the method. This means that if pass the reference you have to your classes you are giving the method a copy of that reference and since both copies reference the same object both the call site and the method will have access to the same instance.
For example:
class Example
{
static void Main()
{
string s = "hello, world";
// Here we are passing a copy of the reference
// stored in "s" to "Print"
Print(s);
}
static void Print(string str)
{
// By default, "str" will be assigned the copy of the
// reference passed to this method.
Console.WriteLine(s);
}
}
I would be careful building an application in which your domain objects (in your case, Boiler, Radiator, etc.) know about the UI layer that consumes them. If you find that you need to pass a Form to one of these domain models you are probably doing something wrong. If you show us a small example of what you are trying to accomplish we might be able to help you come up with a more maintainable solution.

Calling a dynamic function into an object error

I know the title sounds a bit strange, but this has been boggling my mind for a little bit. So Intel offers this TurboBoost sidebar gadget with calls using JavaScript, and I want to write a program from scratch in C# that does the same thing. The calls stem from what I believe is an ActiveX DLL which I easily imported. The problem is, whenever I try to call a function, it gives me the error "an object reference is required for the non-static field..." I've found all of the functions e.g. the one I used return a dynamic data structure. I've tried splitting up the functions and made them both static but still no luck. Here's the code(ITurboBoostClient is the interface portion):
namespace TurboBoostMon_CLI
{
class Program
{
public static object GetCPUFreq()
{
object n = ITurboBoostClient.GetCurBaseFrequency(); //<---- error
//return Convert.ToDouble(n);
return n;
}
public static void Main(string[] args)
{
object cpubasefreq = GetCPUFreq();
Console.WriteLine(cpubasefreq); // neglect the output for now
}
}
}
If typical naming conventions are being used, ITurboBoostClient is an interface, and you do not have an instance of an object that implements the interface. Hence, the error.
Without knowing more about the ActiveX DLL, its hard to say exactly what to do, but it would be along the lines of:
{
ITurboBoostClient myClient = TurboBoostFactory.GetInstance();
object n = myClient.GetCurBaseFrequencey();
return n;
}
Note that in the first line, you call a static method that can product the class (with the interface) that is required. Then you can actually use that interface.
Look again through the ActiveX library you imported, and see if you can find a factory method, a CreateInstance method, or some other instantiator that will create the initial object.
If you're getting that error, then you need to declare something as a new object. Assuming your error marker is correct, you need to change that to create a new instance of some object that inherits the ITurboBoostClient, then use that to call the GetCurBaseFrequenct() method.
Something like:
ITurboBoostClient myTurboBoost = new TurboBoostClientObject(); // Making names up here, not familiar with the framework you're working with.
object n = myTurboBoost.GetCurBaseFrequency();
Sorry I don't know what class you need to instantiate there, but a short dig on google will most surely be revealing.

Doesn't this defeat the whole purpose of having read-only properties?

I know how to use properties and I understand that they implicitly call underlying get and set accessors, depending on whether we are writing to or reading from a property.
static void Main(string[] args)
{
A a = new A();
(a.b).i = 100;
}
class A
{
private B _b = new B();
public B b
{
get { return _b; }
}
}
class B
{
public int i;
}
What code (a.b).i = 100; essentially does is that first property’s get accessor returns a reference to an object _b, and once we have this reference, we are able to access _b’s members and change their values.
Thus, in our example, having read only property only prevents outside code from changing the value of a reference variable _b, but it doesn’t prevent outside code from accessing _b’s members.
So it seems that property can only detect whether we are trying to read from or write to a variable ( in our case variable _b ) located on the stack, while it’s not able to detect whether we’re trying to also write to members of an object to which the variable on the stack ( assuming this variable is of reference type ) points to.
a) But doesn’t that defeat the whole purpose of having read-only properties? Wouldn’t it be more effective if properties had the ability to also detect whether we’re trying to access members of an object returned by get accessor( assuming backing field is of a reference type )?
thank you
Immutability is not transitive; you can't expect mutable objects into an immutable accessor to be immutable.
Your reference is read only, not your object.
Imagine a class like this:
public class A
{
private List<int> _myList<int> = new List<int>();
public List<int> MyList { get { return _myList; } }
}
Now, users of the class can add and remove and access items in the list, but they cannot replace the list itself. This is important. It allows you to do things inside the class like assume the _myList member is never null, for example.
Put a more general way, this paradigm allows you do define an interface into your class such that users can use the types in the properties you expose, but they cannot just swap instances of complex types out from under you.
No, it does not defeat the purpose of read-only properties.
It is possible to use read-only properties that don't let the user change the underlying data. For example, you can have your property return a System.Collections.ObjectModel.ReadOnlyCollection even though the underlying type is a List. This, of course, won't prevent the user from changing the properties of the items in the collection.
Of course you can access B.i; it's public. You're thinking that since _b is private, all methods should be private when fetched through A? In that case it's pretty useless as you wouldn't be able to use B for anything.
You ask:
Doesn’t that defeat the whole purpose
of having read-only properties?
But look: your B.i member is a public field.
I ask you, then: what is the purpose of having a public field? It only makes sense if you want users of your code to be able to change that field's value. If you don't want that, it should be a private field, or (if you want to provide read but not write access) a property with a private set accessor.
So there's your answer. private B _b serves its purpose in the code you posted quite well (_b cannot be externally set to something new), just as public int i serves its purpose equally well (i can be externally changed).
Reference immutability is a popular feature request. Too bad its is so dramatically non CLS compliant. Very few languages have this notion, I only know of C++ (but don't get out much).
The key problem that this needs to be enforced by the CLR. C++ doesn't need to enforce this at runtime, only a C++ compiler is required to ensure that const contracts are observed. It has no support at all for language interop, beyond a bolt-on like COM.
This won't fly in .NET, there's little point in declaring a reference immutable and have that verified by the compiler when another language can stomp all over it because it doesn't have the syntax to express immutability. I reckon we'll get it some day, not Real Soon.
As a minor point, you don't have to write (a.b).i = 100; but simply
a.b.i = 100;
Back to your question, I don't think it defeats the purpose. You can still not do the following:
a.b = new B();
because there's no public set(). If you want the member i of class B to be read only, you can do the same thing as you did to member _b of class A by making it private and providing a public get(), but not set(). Off the top my head, doing what you propose might lead to many unexpected consistencies (I'm sure the language designers did not overlook this).
Entirely dependent on the situation, but read only access to a mutable object is a commonly used design. In many cases you simply want to ensure that the object itself remains the same.
Some classes (like String object in Java, and I believe in C# as well) are entirely immutable, where as others are only partially mutable. Consider an ActiveRecord style of object for which most fields are mutable, but the ID is immutable. If your class holds an ActiveRecord in a read only property, external classes cannot swap it for a different ActiveRecord object and thus change the ID, which might break assumptions within your class.
I disagree. Your property is for the class B, not for the members of class B. This means you can't assign a new Object to b. It doesn't mean that B's public members suddenly become private.
readonly applies to the class property, not the object that the property refers to. It keeps you from being able to write a.b = new B();, and that is all it does. It places no constraints on what you can do to the object once you get a reference to it. I think what you are discovering is that readonly make the most sense when applied to value types or immutable class types.
Another use case:
interface INamedPerson
{
String Name { get; }
}
class Bob : INamedPerson
{
public String Name { get; set; }
}
class Office
{
// initialisation code....
public INamedPerson TheBoss { get; }
public IEnumerable<INamedPerson> Minions { get; }
}
Now, if you have an instance of the Office, as long as you don't go cheating with casts, you have read-only access to everyone's names, but can't change any of them.
Ah. Encapsulation does the instantiated class inherit the containing class's access level. Exposing type B as a public property of type A. 'B.i' is public so it should be accessible from outside the same way 'A.b' is public.
A.b returns a reference of a privately accessible type B, however type B has a publicly accessible field i. My understanding is that you can set the i field of B but you can't set the b property of A externally. The B type property of A is readonly however the reference to type B does not define the same readonly access to its fields.
I'm sure you can modify the definition of type B to suit your need for the access level of B's fields or properties.

How to make a reference type property "readonly"

I have a class Bar with a private field containing the reference type Foo. I would like to expose Foo in a public property, but I do not want the consumers of the property to be able to alter Foo... It should however be alterable internally by Bar, i.e. I can't make the field readonly.
So what I would like is:
private _Foo;
public Foo
{
get { return readonly _Foo; }
}
...which is of course not valid. I could just return a clone of Foo (assumming that it is IClonable), but this is not obvious to the consumer. Should I change the name of the property to FooCopy?? Should it be a GetCopyOfFoo method instead? What would you consider best practice? Thanks!
It sounds like you're after the equivalent of "const" from C++. This doesn't exist in C#. There's no way of indicating that consumers can't modify the properties of an object, but something else can (assuming the mutating members are public, of course).
You could return a clone of the Foo as suggested, or possibly a view onto the Foo, as ReadOnlyCollection does for collections. Of course if you could make Foo an immutable type, that would make life simpler...
Note that there's a big difference between making the field readonly and making the object itself immutable.
Currently, the type itself could change things in both ways. It could do:
_Foo = new Foo(...);
or
_Foo.SomeProperty = newValue;
If it only needs to be able to do the second, the field could be readonly but you still have the problem of people fetching the property being able to mutate the object. If it only needs to do the first, and actually Foo is either already immutable or could be made immutable, you can just provide a property which only has the "getter" and you'll be fine.
It's very important that you understand the difference between changing the value of the field (to make it refer to a different instance) and changing the contents of the object that the field refers to.
Unfortunately, there's no easy way around this in C# at the moment. You could extract the "read only part" of Foo in an interface and let your property return that instead of Foo.
Making a copy, a ReadOnlyCollection, or having Foo be immutable are usually the three best routes, as you've already speculated.
I sometimes favor methods instead of properties whenever I'm doing anything more significant than simply returning the underlying field, depending on how much work is involved. Methods imply that something is going on and raise more of a flag for consumers when they're using your API.
"Cloning" the Foo objects you receive and give back out is a normal practice called defensive copying. Unless there is some unseen side-effect to cloning that will be visible to the user, there is absolutely no reason to NOT do this. It is often the only way to protect your classes' internal private data, especially in C# or Java, where the C++ idea of const is not available. (IE, it must be done in order to properly create truly immutable objects in these two languages.)
Just to clarify, possible side effects would be things like your user (reasonably) expecting that the original object be returned, or some resource being held by Foo that will not be cloned correctly. (In which case, what is it doing implementing IClonable?!)
If you don't want anyone to mess with your state...don't expose it! As others have said, if something needs to view your internal state, provide an immutable representation of it. Alternatively, get clients to tell you to do something (Google for "tell don't ask"), instead of doing it themselves.
To clarify Jon Skeet's comment you can make a view, that is an immutable wrapper class for the mutable Foo. Here's an example:
class Foo{
public string A{get; set;}
public string B{get; set;}
//...
}
class ReadOnlyFoo{
Foo foo;
public string A { get { return foo.A; }}
public string B { get { return foo.B; }}
}
You can actually reproduce the behaviour of C++ const in C# - you just have to do it manually.
Whatever Foo is, the only way the caller can modify its state is by calling methods on it or setting properties.
For example, Foo is of type FooClass:
class FooClass
{
public void MutateMyStateYouBadBoy() { ... }
public string Message
{
get { ... }
set { ... }
}
}
So in your case, you're happy for them to get the Message property, but not set it, and you're definitely not happy about them calling that method.
So define an interface describing what they're allowed to do:
interface IFooConst
{
public string Message
{
get { ... }
}
}
We've left out the mutating method and only left in the getter on the property.
Then add that interface to the base list of FooClass.
Now in your class with the Foo property, you have a field:
private FooClass _foo;
And a property getter:
public IFooConst Foo
{
get { return _foo; }
}
This basically reproduces by hand precisely what the C++ const keyword would do automatically. In psuedo-C++ terms, a reference of type const Foo & is like an automatically generated type that only includes those members of Foo that were marked as const members. Translating this into some theoretical future version of C#, you'd declare FooClass like this:
class FooClass
{
public void MutateMyStateYouBadBoy() { ... }
public string Message
{
get const { ... }
set { ... }
}
}
Really all I've done is merged the information in IFooConst back into FooClass, by tagging the one safe member with a new const keyword. So in a way, adding a const keyword wouldn't add much to the language besides a formal approach to this pattern.
Then if you had a const reference to a FooClass object:
const FooClass f = GetMeAFooClass();
You would only be able to call the const members on f.
Note that if the FooClass definition is public, the caller could cast an IFooConst into a FooClass. But they can do that in C++ too - it's called "casting away const" and involves a special operator called const_cast<T>(const T &).
There's also the issue of interfaces not being very easy to evolve between versions of your product. If a third party may implement an interface you define (which they are free to do if they can see it), then you can't add new methods to it in future versions without requiring others to recompile their code. But that's only a problem if you are writing an extensible library for others to build on. Maybe a built-in const feature would solve this problem.
I was thinking about similar security things. There is probably a way. Quite clear but not short. The general idea is quite simple. However I always found some ways around so never tested it. But you could check it - maybe it will work for you.
This is pseudo code, but I hope idea behind it is clear
public delegate void OnlyRuller(string s1, string s2);
public delegate void RullerCoronation(OnlyRuller d);
class Foo {
private Foo();
public Foo(RullerCoronation followMyOrders) {
followMyOrders(SetMe);
}
private SetMe(string whatToSet, string whitWhatValue) {
//lot of unclear but private code
}
}
So in class which creates this property you have access to SetMe method, but it's still private so except for creator Foo looks unmutable.
Still for anything bigger than few properties this will probably became soon super mess - that's why I always preferred other ways of encapsulation. However if it's super important for you to not allow the client to change Foo, than this is one alternative.
However, as I said, this is only theory.

Categories

Resources