How to Get a Reference to a 'Dynamic' Object Call

How do I dynamically call a reference name of an object from an if statement?

The problem is that you have owner as an Object reference, which doesn't have the money field. You need to use the Player class instead:

public class Property
{
boolean available=false;
Player owner;
int rent = 0;
int houses = 0;
int hotels = 0;
}

And then you can directly move the rent between the two players, e.g.:

Property property = Monopoly.mediterranean;
activePlayer.money-= property.rent;
property.owner.money+= property.rent;

In a real game you would then add more checks, e.g. does the player have enough money to cover the rent or are there problems with parallelism that need to be covered, but that is the basic solution to your problem.

How do I reference an object dynamically?

short answer: obj[a]

long answer: obj.field is just a shorthand for obj["field"], for the special case where the key is a constant string without spaces, dots, or other nasty things. in your question, the key wasn't a constant, so simply use the full syntax.

Returning/Passing an dynamically allocated object by Reference

You are thinking about this the wrong way. You don't dynamically allocate a new object. You dynamically (re)allocate the data of the object that is being assigned/concatenated to, and then return a reference to that object, not a reference to a new allocated object.

If you really want to implement this manually in a string-like class (instead of using the standard std::string class), then try something more like this:

class String346 {
private:
char *data;
unsigned int size;

public:
String346();
String346(const char *oldString);
String346(const String346 &oldString);
~String346();

//...

String346& operator=(const String346 &newString);

//...

String346& concat(const String346 &catString);

//...
};

String346::String346() : data(NULL), size(0) {
}

String346::String346(const char * oldString) : data(NULL), size(std::strlen(oldString)) {
data = new char[size+1];
std::copy_n(oldString, size, data);
data[size] = 0;
}

String346::String346(const String346 &oldString) : data(NULL), size(oldString.size) {
data = new char[size+1];
std::copy_n(oldString.data, size, data);
data[size] = 0;
}

String346::~String346() {
delete[] data;
}

String346& operator=(const String346 &newString) {
String346 tmp(newString);
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

String346 & String346::concat(const String346 &catString) {
String346 tmp;
tmp.size = size + catString.size;
tmp.data = new char[tmp.size+1];
std::copy_n(data, size, tmp.data);
std::copy_n(catString.data, catString.size, tmp.data+size);
tmp.data[tmp.size] = 0;
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

Technically, you do not have to implement a char* version of either operator=() or concat() since they both take const String346& as input and String346 has a constructor that accepts a char* as input. If you pass a char* to one of them, the compiler will automatically construct and destruct a temporary String346 object for you:

String346 s;
s = "hello"; // calls s.operator=(String346("hello"))...
s.concat("world"); // calls s.concat(String346("world"))...

Though, for optimization purposes, it might make sense to do so, to avoid unnecessary allocations of temporary memory (unless you implement move semantics in C++11):

class String346 {
private:
char *data;
unsigned int size;

public:
String346();
String346(const char *oldString);
String346(const String346 &oldString);
~String346();

//...

String346& operator=(const char *newString);
String346& operator=(const String346 &newString);

//...

String346& concat(const char *catString);
String346& concat(const String346 &catString);

//...
};

String346::String346() : data(NULL), size(0) {
}

String346::String346(const char * oldString) : data(NULL), size(std::strlen(oldString)) {
data = new char[size+1];
std::copy_n(oldString, size, data);
data[size] = 0;
}

String346::String346(const String346 &oldString) : data(NULL), size(oldString.size) {
data = new char[size+1];
std::copy_n(oldString.data, size, data);
data[size] = 0;
}

String346::~String346() {
delete[] data;
}

String346& operator=(const char *newString) {
String346 tmp(newString);
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

String346& operator=(const String346 &newString) {
String346 tmp(newString);
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

String346 & String346::concat(const char *catString) {
unsigned int catSize = std::strlen(catString);
String tmp;
tmp.size = size + catSize;
tmp.data = new char[tmp.size+1];
std::copy_n(data, size, tmp.data);
std::copy_n(catString, catSize, tmp.data+size);
tmp.data[tmp.size] = 0;
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

String346 & String346::concat(const String346 & catString) {
String tmp;
tmp.size = size + catString.size;
tmp.data = new char[tmp.size+1];
std::copy_n(data, size, tmp.data);
std::copy_n(catString.data, catString.size, tmp.data+size);
tmp.data[tmp.size] = 0;
std::swap(data, tmp.data);
size = tmp.size;
return *this;
}

Dynamic variable in Javascript (call by reference)

Is there any way to achieve this?

Not directly. All you can do is pass an object and have the function modify a property on it, as in your first example. JavaScript does not have pass-by-reference, just pass-by-value. (The value may be an object reference, of course, but it's still a value.) There's no way in JavaScript to directly modify the variable/property you're passing into the function, because what the function receives is a copy of the value of that variable/property, not a reference to that variable/property.


Just to be clear about something: In your first code block, you said you were "sending the object to the function." That's incorrect. You send a reference to the object to the function.

This is the key thing to understand: Variables, properties, and function arguments (collectively, "variables") contain values, and those values are copied when you use assignment or when you pass them into functions. The value that refers to an object is called an object reference, because the value isn't the object, it's a reference to (pointer to) the object elsewhere in memory. The reference is copied when you pass it into a function, the object is not.

Don't confuse the "reference" in "object reference" with the "reference" in "pass-by-reference," they're completely different things. (In pass-by-reference, the reference is to the variable, not an object. JavaScript doesn't have pass-by-reference.)

Dynamic object reference C#

Assuming you want to keep the data structure the way it is (not recommended-- see comments), the obvious code simplification would be:

var d = new Data
{
variable0 = listData[0];
};
if (number >= 1) d.variable1 = listData[1];
if (number >= 2) d.variable2 = listData[2];
if (number >= 3) d.variable3 = listData[3];
_newData.Add(d);

Accessing an object property with a dynamically-computed name

There are two ways to access properties of an object:

  • Dot notation: something.bar
  • Bracket notation: something['bar']

The value between the brackets can be any expression. Therefore, if the property name is stored in a variable, you have to use bracket notation:

var something = {
bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

How do I get reference to an instance of an object from a dynamic created class

Basically, once you found the MethodInfo you want on the Type you created from the user's code, there is no problem with just sending it the object as a parameter. As in:

object userType = ... // compile user's code, load user's type from compiled assembly
MethodInfo myMethod = ... // find the wanted method on the user's type

// assuming the user code is in a static method to avoid having to create instances.
myMethod.Invoke(null, targetObj);

If you want the user to only have to writa:

theObject.Color;

Then you should wrap the user's code to produce something like that:

// BEGIN PREFIX
public static class UserType
{
public static UserMethod(TheObject theObject);
{
// END PREFIX, user code follows

theObject.Color = Color.Red;

// BEGIN SUFFIX
}
}
// END SUFFIX

By the way, there are some serious security consequences to the design that you chose.

For example, nothing can prevent the user code from doing things that will cause your application to terminate, become unresponsive, or other stuff. Intentionally or not. For example, if the user enters something like System.Windows.Forms.Application.Exit();, there's nothing you can do.

The solution to such volnurabilities would be run the user code in a separate AppDomain, and send to it the target object, for example through Remoting.

Edit: Trying to suggest a way that would not require passing the object as a parameter.

You can create an Assembly with a single class that would expose a static instance of your object. Something like:

public class TheInstance
{
public static TheObject TheObject = new TheObject();
}

So now the user code will be able to do things like:

TheInstance.TheObject.Color = Color.Red;

And you will not have to bother with sending the parameter.

In order for the user code to be able to access the class in this assembly, all you have to do is specify this assembly as a reference when you use the ICodeCompiler to compile the user code.

Is that what you were looking for?



Related Topics



Leave a reply



Submit