By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,272 Members | 1,408 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,272 IT Pros & Developers. It's quick & easy.

Pass a class object (this) by reference

P: n/a
Hello, I am needing to pass a class object (this) by reference to a method
in a different class. When I do the following code I get the error (Cannot
pass '<this>' as a ref or out argument because it is read-only) .. Is there
any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO


Nov 15 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Your trying to pass ref to taskId which is an int. In your GetTaskFromId
method, the signature is a Task type. I think you may want
"data.GetTaskFromId( data );" You don't need the "ref" to give TaskData
access to members of this object. Remove the ref and change the taskId to
data in your method call, and this should do what you want.
--wjs mvp

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:u0**************@TK2MSFTNGP09.phx.gbl...
Hello, I am needing to pass a class object (this) by reference to a method
in a different class. When I do the following code I get the error (Cannot pass '<this>' as a ref or out argument because it is read-only) .. Is there any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO

Nov 15 '05 #2

P: n/a
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as
a ref or out argument because it is read-only" The line that I adjusted is
"data.GetTaskFromId(this);" in the Task class. My appologies for not double
checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(this);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

--
Jay Douglas
Fort Collins, CO

"William Stacey" <st***********@mvps.org> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Your trying to pass ref to taskId which is an int. In your GetTaskFromId
method, the signature is a Task type. I think you may want
"data.GetTaskFromId( data );" You don't need the "ref" to give TaskData
access to members of this object. Remove the ref and change the taskId to
data in your method call, and this should do what you want.
--wjs mvp

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:u0**************@TK2MSFTNGP09.phx.gbl...
Hello, I am needing to pass a class object (this) by reference to a method in a different class. When I do the following code I get the error

(Cannot
pass '<this>' as a ref or out argument because it is read-only) .. Is

there
any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO


Nov 15 '05 #3

P: n/a
Jay Douglas <RE*********************************@squarei.com > wrote:
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as
a ref or out argument because it is read-only" The line that I adjusted is
"data.GetTaskFromId(this);" in the Task class. My appologies for not double
checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.


I don't see *why* you're trying to pass it by reference in the first
place - could you explain?

You *may* misunderstand what passing parameters by reference is really
about. See
http://www.pobox.com/~skeet/csharp/parameters.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #4

P: n/a

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:OQ**************@TK2MSFTNGP09.phx.gbl...
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as a ref or out argument because it is read-only" The line that I adjusted is "data.GetTaskFromId(this);" in the Task class. My appologies for not double checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(this);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

--
Jay Douglas
Fort Collins, CO

"William Stacey" <st***********@mvps.org> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Your trying to pass ref to taskId which is an int. In your GetTaskFromId
method, the signature is a Task type. I think you may want
"data.GetTaskFromId( data );" You don't need the "ref" to give TaskData
access to members of this object. Remove the ref and change the taskId to data in your method call, and this should do what you want.
--wjs mvp

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:u0**************@TK2MSFTNGP09.phx.gbl...
Hello, I am needing to pass a class object (this) by reference to a

method in a different class. When I do the following code I get the error

(Cannot
pass '<this>' as a ref or out argument because it is read-only) .. Is

there
any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO


The problem might be the passing of the Task object before it is completely
constructed.

bob
Nov 15 '05 #5

P: n/a
Jon,

The reason I want to pass (this) is because the data class makes multiple
changes to the task object and I don't want to have to reset all the
properties back in the Task object. What I'm trying to avoid is needing to
do something like:

(This is how I currently do it with out the references, the data class
returns a new task object)
Task task data.GetTaskFromId(this);
this.Property1 = task.Property1
this.Property2 = task.Property2

I need to break out all of the data classes because a project implementation
may use the database (MS SQL, LDAP, MySQL) or the file system.

I would like to change (this) in another class without needing to reset all
of the properties. This is a has been a development issue for me across the
board. I'm not opposed to a different development pattern to address this
issue. I would just like to come up with something.

All suggestions are appreciated.
--
Jay Douglas
Fort Collins, CO

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Jay Douglas <RE*********************************@squarei.com > wrote:
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as a ref or out argument because it is read-only" The line that I adjusted is "data.GetTaskFromId(this);" in the Task class. My appologies for not double checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.


I don't see *why* you're trying to pass it by reference in the first
place - could you explain?

You *may* misunderstand what passing parameters by reference is really
about. See
http://www.pobox.com/~skeet/csharp/parameters.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #6

P: n/a
Jay Douglas <RE*********************************@squarei.com > wrote:
The reason I want to pass (this) is because the data class makes multiple
changes to the task object and I don't want to have to reset all the
properties back in the Task object.
You don't. As I thought, you don't quite understand what pass-by-
reference does, or what reference types are in .NET. Read the page I
linked to before.

<snip>
I would like to change (this) in another class without needing to reset all
of the properties.


You can change the properties *of* "this" but you can't change which
object "this" is a reference to. It doesn't really make sense (IMO) to
be able to do

this = new Task();

which is what you'd be allowing yourself to do if you could pass this
by reference.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7

P: n/a
You still don't need the "ref" in there, unless I miss what your trying to
do. Remove the ref and see if that does what you need.

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:OQ**************@TK2MSFTNGP09.phx.gbl...
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as a ref or out argument because it is read-only" The line that I adjusted is "data.GetTaskFromId(this);" in the Task class. My appologies for not double checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(this);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

--
Jay Douglas
Fort Collins, CO

"William Stacey" <st***********@mvps.org> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Your trying to pass ref to taskId which is an int. In your GetTaskFromId
method, the signature is a Task type. I think you may want
"data.GetTaskFromId( data );" You don't need the "ref" to give TaskData
access to members of this object. Remove the ref and change the taskId to data in your method call, and this should do what you want.
--wjs mvp

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:u0**************@TK2MSFTNGP09.phx.gbl...
Hello, I am needing to pass a class object (this) by reference to a

method in a different class. When I do the following code I get the error

(Cannot
pass '<this>' as a ref or out argument because it is read-only) .. Is

there
any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO



Nov 15 '05 #8

P: n/a
100
Hi Jay,
Just remove the ref modifier form the task parameter of GetTaskFromId
method. Since Task is a class (reference type) you pass references to its
instances anyway. Making task parameter *ref* means that changing the value
of the formal parameter (task) will change the value of the actual parameter
used for the method call. You cannot change *this*. That's why the compiler
reports an error and says that *this* is readonly.

So, once again my siggestion is to remove the *ref* modifier from the *task*
parameter of GetTaskFromId method.

HTH
B\rgds
100

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:OQ**************@TK2MSFTNGP09.phx.gbl...
You know what, I hastily broke down that code. The code I provided is
incorrect. Please view the new code for the error "Cannot pass '<this>' as a ref or out argument because it is read-only" The line that I adjusted is "data.GetTaskFromId(this);" in the Task class. My appologies for not double checking my post.

I have simplified the following code. There is a Task class and a Data
Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(this);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

--
Jay Douglas
Fort Collins, CO

"William Stacey" <st***********@mvps.org> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Your trying to pass ref to taskId which is an int. In your GetTaskFromId
method, the signature is a Task type. I think you may want
"data.GetTaskFromId( data );" You don't need the "ref" to give TaskData
access to members of this object. Remove the ref and change the taskId to data in your method call, and this should do what you want.
--wjs mvp

"Jay Douglas" <RE*********************************@squarei.com > wrote in
message news:u0**************@TK2MSFTNGP09.phx.gbl...
Hello, I am needing to pass a class object (this) by reference to a

method in a different class. When I do the following code I get the error

(Cannot
pass '<this>' as a ref or out argument because it is read-only) .. Is

there
any way to make <this> not read-only?

I have simplified the following code. There is a Task class and a Data Class. I am trying to pass the task class by ref to the data class.

public class Task
{
public Task(int taskId)
{
TaskData data = new TaskData();
data.GetTaskFromId(ref taskId);
data.Close();
}
}

public class TaskData
{
public void GetTaskFromId(ref Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));

SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

All suggestions are appreicated.

Thanks!

--
Jay Douglas
Fort Collins, CO



Nov 15 '05 #9

P: n/a
Jon,
It looks like I was really missing the big picture. You advise was
really helpful and gave me a sold answer. Here is the modified code that
works:

public class Task
{
public Task(int taskId)
{
this.taskId = taskId;

TaskData data = new TaskData();
data.GetTaskFromId(this);
data.Close();

Console.WriteLine(this.Name); // Out puts the change
// that the data class
// made to the Task object
}
}

public class TaskData
{
internal void GetTaskFromId(Task task)
{
SqlCommand cmd = new SqlCommand("sp_Task_GetByID_Select", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@TaskID", task.TaskId));
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
task.TaskId = Convert.ToInt32(reader["TaskId"]);
task.Name = reader["Name"].ToString();
task.Description = reader["Descr"].ToString();
}

reader.Close();
cmd.Dispose();

}
}

--
Jay Douglas
Fort Collins, CO

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Jay Douglas <RE*********************************@squarei.com > wrote:
The reason I want to pass (this) is because the data class makes multiple changes to the task object and I don't want to have to reset all the
properties back in the Task object.


You don't. As I thought, you don't quite understand what pass-by-
reference does, or what reference types are in .NET. Read the page I
linked to before.

<snip>
I would like to change (this) in another class without needing to reset all of the properties.


You can change the properties *of* "this" but you can't change which
object "this" is a reference to. It doesn't really make sense (IMO) to
be able to do

this = new Task();

which is what you'd be allowing yourself to do if you could pass this
by reference.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.