I am trying to change a struct values (located in class A) from another class (class B per say) I wrote a method to get the struct (the method is located in class A) but all I get is a shallow copy (the values do not really change...) any help?
Yes, that's what happens with structs. You need to make the changes locally, then shallow copy back again. For example:
public class Foo
{
public Point Location { get; set; }
}
public class Bar
{
private Foo foo = new Foo();
public void MoveFoo()
{
Point location = foo.Location;
location.X += 10;
location.Y += 20;
// Copy it back
foo.Location = location;
}
}
Personally I try to avoid making structs mutable in the first place - but will often given them what I call "pseudo-mutator" methods which return a new value with appropriate changes. So for example, for a Point struct I might have a method like this:
public Point TranslatedBy(int dx, int dy)
{
return new Point(x + dx, y + dy);
}
Then the MoveFoo method above would be:
foo.Location = foo.Location.TranslatedBy(10, 20);
Related
import java.awt.Point;
import java.util.ArrayList;
import java.util.Scanner;
public class Path
{
ArrayList<Point> pointOne;
ArrayList<Point> pointTwo;
public Path() {
pointOne = new ArrayList<Point>();
pointTwo = new ArrayList<Point>();
}
public Path(Scanner s)
{
pointOne = new ArrayList<Point>();
pointTwo = new ArrayList<Point>();
}
public int getPointCount()
{
return 0;
}
public int getX(int n)
{
return n;
}
public int getY(int n)
{
return n;
}
public void add(int x, int y)
{
}
public String toString()
{
}
So far this is what I have for the getX and getY function, please feel free to correct me if im not doing something right.
I've tried to research some different ways to add two points to an arraylist. I found one here but it didn't help as much as I thought it was going to. I am also confused on how to use the scanner to scan in the points and build a path. Am I just being dumb and overthinking this? I'm going to talk to my teacher to see if he can clear anything up but any help would be much appreciated thanks
public class Main {
public static void main {
ArrayList<Point> path = new ArrayList<Point>();
path.add(new Point(x1,y1));
path.add(new Point(x2,y2));
}
}
public class Point {
private double X;
private double Y;
public Point(double x, double y){
X = x;
Y = y;
}
public double getX(){return X;}
public double getY(){return Y;}
}
You see, a path is a list of points, conceptually, specifically an ArrayList of Points here. Point is a type of object with attributes x and y. You don't need to create an type called Path because a Path is just an ArrayList<Point>. You can't extend ArrayLists, probably you don't know yet about how inheritance anyways. But unless you are told specifically to do so, there's no need to make Path a class.
Furthermore, Point could be removed as a type and just made as an ArrayList<Double>. Conceptually, a point is just a list of its numeric coordinates in each direction.
Therefore, a Path could be represented as an ArrayList<ArrayList<Double>>.
In the section on handling Java Beans with Groovy of Groovy In Action, I found this script (slightly modified):
class Book{
String title
}
def groovyBook = new Book()
// explicit way
groovyBook.setTitle('What the heck, really ?')
println groovyBook.getTitle()
// short-hand way
groovyBook.title = 'I am so confused'
println groovyBook.title
There are no such methods in the class Book so how does that work ?
Yes, they are auto defined and calling book.title is actually calling book.getTitle()
See http://groovy.codehaus.org/Groovy+Beans
You can see this in action with the following script:
def debug( clazz ) {
println '----'
clazz.metaClass.methods.findAll { it.name.endsWith( 'Name' ) || it.name.endsWith( 'Age' ) }.each { println it }
}
class A {
String name
int age
}
debug( A )
// Prints
// public int A.getAge()
// public java.lang.String A.getName()
// public void A.setAge(int)
// public void A.setName(java.lang.String)
// Make name final
class B {
final String name
int age
}
debug( B )
// Prints
// public int B.getAge()
// public java.lang.String B.getName()
// public void B.setAge(int)
// Make name private
class C {
private String name
int age
}
debug( C )
// Prints
// public int C.getAge()
// public void C.setAge(int)
// Try protected
class D {
protected String name
int age
}
debug( D )
// Prints
// public int D.getAge()
// public void D.setAge(int)
// And public?
class E {
public String name
int age
}
debug( E )
// Prints
// public int E.getAge()
// public void E.setAge(int)
Several notes:
For all property fields(public ones only), there are autogenerated accesors.
Default visibility is public. So, you should use private/protected keyword to restrict accessor generation.
Inside an accessor there is direct field access. like this.#title
Inside a constructor you have direct access to! This may be unexpected.
For boolean values there are two getters with is and get prefixes.
Each method with such prefixes, even java ones are treated as accessor, and can be referenced in groovy using short syntax.
But sometimes, if you have ambiguous call there may be class cast exception.
Example code for 4-th point.
class A{
private int i = 0;
A(){
i = 4
println("Constructor has direct access. i = $i")
}
void setI(int val) { i = val; println("i is set to $i"); }
int getI(){i}
}
def a = new A() // Constructor has direct access. i = 4
a.i = 5 // i is set to 5
println a.i // 5
4-th note is important, if you have some logic in accessor, and want it to be applied every time you call it. So in constructor you should explicit call setI() method!
Example for 7
class A{
private int i = 0;
void setI(String val) { println("String version.")}
void setI(int val) { i = val; println("i is set to $i"); }
}
def a = new A()
a.i = 5 // i is set to 5
a.i = "1s5" // GroovyCastException: Cannot cast object '1s5' with class 'java.lang.String' to class 'int'
So, as I see property-like access uses first declared accessor, and don't support overloading. Maybe will be fixed later.
Groovy generates public accessor / mutator methods for fields when and only when there is no access modifier present. For fields declared as public, private or protected no getters and setters will be created.
For fields declared as final only accessors will be created.
All that applies for static fields analogously.
I'm looking at the source code for JDK 7 - specifically WeakHashMap.java, where there is extensive use of this:
Entry<K,V> p = prev;
Entry<K,V> next = p.next;
but next isn't a method defined on Map.Entry (as far as I can see? http://docs.oracle.com/javase/7/docs/api/java/util/Map.Entry.html)
Where is the call to this method coming from then?
WeakHashMap is not referring to Map.Entry, but instead, to its own internal implementation of the Map.Entry interface, a class named Entry. That class has a field named next, which it can access.
next is not a function. It is a member variable of a class that is being directly accessed. Typically you would see this (in OO code)
public class Foo
{
String bar;
public String getBar()
{
return this.bar;
}
}
The .next syntax you see is what is commonly referred to as direct member access and is typically frowned upon.
It is an inner class inside WeakHashMap, which contains a reference to Entry next:
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V>{
V value;
final int hash;
Entry<K,V> next;
Entry(Object key, V value, ReferenceQueue<Object> queue, int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
// omit others...
}
Check out the source code at line 682: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/WeakHashMap.java#WeakHashMap.Entry
This is the same thing for HashMap. It has similar inner class:
static class Entry<K, V> implements Map.Entry<K, V>
Is it possible to create an object with a constructor parameter which returns a property value when referenced, without using dot notation? Here's a few examples:
public class myObject
{
public string myObject {get; private set;}
public myObject( string tempstring)
{
this.myObject = tempstring.ToUpper();
}
}
var a = new myObject("somevalue");
Console.WriteLine( myObject ); // outputs the string "SOMEVALUE"
Here's another attempt:
public class myInt
{
public int myInt {get; private set;}
public myInt(string tempInt)
{ this.myInt = Convert.ToInt32(tempInt);
}
}
var a = new myInt("3");
var b = a + a; // ends up being an int datatype value of 6
I know I could always do var b = a.myInt + a.myInt. I guess I could create a static class with a static function that converts a parameter each time to a result, but it wouldn't maintain state.
Just curious. It would make what I am actually trying to do much less difficult.
In the first case, yes. Override the ToString method.
public class myObject
{
public string myValue {get; private set;}
public myObject( string tempstring)
{
this.myValue = tempstring.ToUpper();
}
public override string ToString()
{
return myValue;
}
}
In the second case, sort of. You shouldn't try to overload operators to offer unexpected behavior. Create a method to perform behavior that wouldn't make sense when reading the code. What you are suggesting (returning an int) would definitely not be expected by me to return an int (mostly because of the var rather than a strictly defined type). Using the + operator to return a new myInt object would make sense. Using the + operator return an int would not.
You could overload the + operator to return a new myInt object, and then also add an implicit cast to int. Just make sure it makes sense, and that it is readable.
Within the class, you could use:
public static implicit operator int(myInt m)
{
return myValue;
}
public static myInt operator +(myInt left, myInt right)
{
// requires constructor that takes int
return new myInt(left.myValue + right.myValue);
}
Of course, you could go the direct route, but again only use it when it makes it more readable and not less (note, just like methods operators cannot be overloaded simply by return type, so you'd have to pick between the two).
public static int operator +(myInt left, myInt right)
{
return left.myValue + right.myValue;
}
How about implicit conversions. See http://msdn.microsoft.com/en-us/library/z5z9kes2(VS.71).aspx
I was just trying to code the following extension method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _4Testing
{
static class ExtensionMethods
{
public static void AssignMe(this int me, int value)
{
me = value;
}
}
}
But it is not working, i mean, can I use an extension method to alter values from extended classes? I don't want to change void return type to int, just changing extended class value. Thanks in advance
Your example uses int, which is a value type. Classes are reference types and behaves a bit differently in this case.
While you could make a method that takes another reference like AssignMe(this MyClass me, MyClass other), the method would work on a copy of the reference, so if you assign other to me it would only affect the local copy of the reference.
Also, keep in mind that extension methods are just static methods in disguise. I.e. they can only access public members of the extended types.
public sealed class Foo {
public int PublicValue;
private int PrivateValue;
}
public static class FooExtensions {
public static void Bar(this Foo f) {
f.PublicValue = 42;
// Doesn't compile as the extension method doesn't have access to Foo's internals
f.PrivateValue = 42;
}
}
// a work around for extension to a wrapping reference type is following ....
using System;
static class Program
{
static void Main(string[] args)
{
var me = new Integer { value = 5 };
int y = 2;
me.AssignMe(y);
Console.WriteLine(me); // prints 2
Console.ReadLine();
}
public static void AssignMe(this Integer me, int value)
{
me.value = value;
}
}
class Integer
{
public int value { get; set; }
public Integer()
{
value = 0;
}
public override string ToString()
{
return value.ToString();
}
}
Ramon what you really need is a ref modifier on the first (i.e. int me ) parameter of the extension method, but C# does not allow ref modifier on parameters having 'this' modifiers.
[Update]
No workaround should be possible for your particular case of an extension method for a value type. Here is the "reductio ad absurdum" that you are asking for if you are allowed to do what you want to do; consider the C# statement:
5.AssignMe(10);
... now what on earth do you think its suppose to do ? Are you trying to assign 10 to 5 ??
Operator overloading cannot help you either.
This is an old post but I ran into a similar problem trying to implement an extender for the String class.
My original code was this:
public static void Revert(this string s)
{
char[] xc = s.ToCharArray();
s = new string(xc.Reverse());
}
By using the new keyword I am creating a new object and since s is not passed by reference it will not be modified.
I changed it to the following which provides a solution to Ramon's problem:
public static string Reverse(this string s)
{
char[] xc = s.ToCharArray();
Array.Reverse(xc);
return new string(xc);
}
In which case the calling code will be:
s = s.Reverse();
To manipulate integers you can do something like:
public static int Increment(this int i)
{
return i++;
}
i = i.Increment();