473,394 Members | 1,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

structs and 'using'

A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?
Nov 16 '05 #1
11 1982
the struct is being boxed I believe, therefore the error is generated because
you'd never been able to assign value to the original struct with that line
of code.

"Nemanja Trifunovic" wrote:
A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?

Nov 16 '05 #2
The struct will indeed get boxed when the "using" statement gets a reference
to the IDisposable interface. On the other hand, variable "s" should be the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}

Regards,
Daniel

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:9D**********************************@microsof t.com...
the struct is being boxed I believe, therefore the error is generated because you'd never been able to assign value to the original struct with that line of code.

"Nemanja Trifunovic" wrote:
A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?

Nov 16 '05 #3
Hmm...

I do not have a quick answer to this. To test this, I wrote a simple
program and disassembled it. The code should expand to the following:

C s;
s = new C();
try { s.clan =1 } finally { s.Dispose(); }

If you hand-code this instead of leveraging the "using" statement, this code
compiles fine. There must be something to the fact that C is a struct vs. a
class (try changing "stuct" to "class" to see everything work fine in your
original). In addition, even if you do not inherit from IDispose (or
anything else, for that matter and leave the struct a plain vanilla struct),
the compiler still complains.

I'd be interested in the reply as well...

John

"Nemanja Trifunovic" <nt*********@hotmail.com> wrote in message
news:82**************************@posting.google.c om...
A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?

Nov 16 '05 #4
Daniel and Daniel,

The structure does not get boxed. The compiler realizes that the
structure has a public Dispose method and calls it directly on the
structure. It is never boxed.

The reason for this is that certain constructs cause the object
mentioned in them to be readonly. The using statement and the foreach
statement are the two offhand that I remember in C# that you can not change.
For most reference types, if you do something like this:

using (MyClass s = new MyClass())
{

}

You can change properties of s, but you can't change s itself. Because
you are using a structure, and it is not a reference, it is not allowed to
be changed.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Daniel Pratt" <ko******************@hotmail.com> wrote in message
news:eD**************@TK2MSFTNGP15.phx.gbl...
The struct will indeed get boxed when the "using" statement gets a
reference
to the IDisposable interface. On the other hand, variable "s" should be
the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}

Regards,
Daniel

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:9D**********************************@microsof t.com...
the struct is being boxed I believe, therefore the error is generated

because
you'd never been able to assign value to the original struct with that

line
of code.

"Nemanja Trifunovic" wrote:
> A question for C# language experts:
>
> If I have a struct that implements IDisposable:
>
> struct C : IDisposable
> {
> public int clan;
> public void Dispose()
> {
> Console.WriteLine("Disposing");
> }
> }
>
>
> And later in the code something like:
> using (C s = new C())
> {
> s.clan = 1;
> }
>
>
> A compiler error is reported:
> error CS0131: The left-hand side of an assignment must be a variable,
> property or indexer
>
> Why does that happen?
>


Nov 16 '05 #5
John,

The fact that it is only a structure is part of the reason. The target
of a "using" statement and a "foreach" statement can not be modified. In
the case of a reference type, that means the reference. In the case of a
value type, that means the whole structure.

By "target", I mean the instance that is created in the statement. If
you are using an existing variable, then the restriction does not apply.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"John Puopolo" <jo**********@fastsearch.com.nospam> wrote in message
news:eE****************@TK2MSFTNGP15.phx.gbl...
Hmm...

I do not have a quick answer to this. To test this, I wrote a simple
program and disassembled it. The code should expand to the following:

C s;
s = new C();
try { s.clan =1 } finally { s.Dispose(); }

If you hand-code this instead of leveraging the "using" statement, this
code
compiles fine. There must be something to the fact that C is a struct vs.
a
class (try changing "stuct" to "class" to see everything work fine in your
original). In addition, even if you do not inherit from IDispose (or
anything else, for that matter and leave the struct a plain vanilla
struct),
the compiler still complains.

I'd be interested in the reply as well...

John

"Nemanja Trifunovic" <nt*********@hotmail.com> wrote in message
news:82**************************@posting.google.c om...
A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?


Nov 16 '05 #6

"Daniel Pratt" <ko******************@hotmail.com> wrote in message
news:eD**************@TK2MSFTNGP15.phx.gbl...
The struct will indeed get boxed when the "using" statement gets a
reference
to the IDisposable interface. On the other hand, variable "s" should be
the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}


First of all, why would you ever have a Disposable struct?

But putting that aside, this is not a bug.

From the C# Language Specification
http://msdn.microsoft.com/library/de...pspec_8_13.asp

Local variables declared in a resource-acquisition are read-only, and must
include an initializer. A compile-time error occurs if the embedded
statement attempts to modify these local variables (by assignment or the ++
and -- operators) or pass them as ref or out parameters.

This works fine:
Nov 16 '05 #7
as always, you are right Nick. I was just thinking, it wouldn't really had
made sense that a value type will be boxed when an method is called, like
DateTime.AddXXX. so I looked in the IL and there's no box.

"Nicholas Paldino [.NET/C# MVP]" wrote:
Daniel and Daniel,

The structure does not get boxed. The compiler realizes that the
structure has a public Dispose method and calls it directly on the
structure. It is never boxed.

The reason for this is that certain constructs cause the object
mentioned in them to be readonly. The using statement and the foreach
statement are the two offhand that I remember in C# that you can not change.
For most reference types, if you do something like this:

using (MyClass s = new MyClass())
{

}

You can change properties of s, but you can't change s itself. Because
you are using a structure, and it is not a reference, it is not allowed to
be changed.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Daniel Pratt" <ko******************@hotmail.com> wrote in message
news:eD**************@TK2MSFTNGP15.phx.gbl...
The struct will indeed get boxed when the "using" statement gets a
reference
to the IDisposable interface. On the other hand, variable "s" should be
the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}

Regards,
Daniel

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:9D**********************************@microsof t.com...
the struct is being boxed I believe, therefore the error is generated

because
you'd never been able to assign value to the original struct with that

line
of code.

"Nemanja Trifunovic" wrote:

> A question for C# language experts:
>
> If I have a struct that implements IDisposable:
>
> struct C : IDisposable
> {
> public int clan;
> public void Dispose()
> {
> Console.WriteLine("Disposing");
> }
> }
>
>
> And later in the code something like:
> using (C s = new C())
> {
> s.clan = 1;
> }
>
>
> A compiler error is reported:
> error CS0131: The left-hand side of an assignment must be a variable,
> property or indexer
>
> Why does that happen?
>



Nov 16 '05 #8
David,

I would never implement Dispose on a struct, but I would have a struct
that has a public dispose method to do scope cleanup. For example, I have a
struct that performs an operation like a data adapter, where it will take a
connection, and if it is closed, will close it, and if open, will keep it
open. When it disposes, it will leave the connection state the way it found
it.

It is placed in a struct specifically to be used in a using statement as
a perf enhancement. Having an object do this would require the object to be
cleaned up at a later time, instead of being wiped away with the stack.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"David Browne" <davidbaxterbrowne no potted me**@hotmail.com> wrote in
message news:u7*************@TK2MSFTNGP10.phx.gbl...

"Daniel Pratt" <ko******************@hotmail.com> wrote in message
news:eD**************@TK2MSFTNGP15.phx.gbl...
The struct will indeed get boxed when the "using" statement gets a
reference
to the IDisposable interface. On the other hand, variable "s" should be
the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}


First of all, why would you ever have a Disposable struct?

But putting that aside, this is not a bug.

From the C# Language Specification

http://msdn.microsoft.com/library/de...pspec_8_13.asp

Local variables declared in a resource-acquisition are read-only, and must
include an initializer. A compile-time error occurs if the embedded
statement attempts to modify these local variables (by assignment or the
++ and -- operators) or pass them as ref or out parameters.

This works fine:

Nov 16 '05 #9
"Daniel Pratt" wrote:
The struct will indeed get boxed when the "using" statement gets a reference
to the IDisposable interface. On the other hand, variable "s" should be the
original unboxed struct and therefore it should be possible to do what is
being done. I say it's a bug. Especially since this will work:

C s = new C();

using (s)
{
s.clan = 1;
}

this works because apparently right after initobj of 's', a second copy is
made, and Dispose method is called off of this second copy, leaving the
original copy of 's' free to be modified.
Regards,
Daniel

"Daniel Jin" <Da*******@discussions.microsoft.com> wrote in message
news:9D**********************************@microsof t.com...
the struct is being boxed I believe, therefore the error is generated

because
you'd never been able to assign value to the original struct with that

line
of code.

"Nemanja Trifunovic" wrote:
A question for C# language experts:

If I have a struct that implements IDisposable:

struct C : IDisposable
{
public int clan;
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
And later in the code something like:
using (C s = new C())
{
s.clan = 1;
}
A compiler error is reported:
error CS0131: The left-hand side of an assignment must be a variable,
property or indexer

Why does that happen?


Nov 16 '05 #10
I rather like IanG's TimedLock struct which implements IDisposable:

http://www.interact-sw.co.uk/iangblo.../03/23/locking

and EricGu's comments here:

http://blogs.msdn.com/ericgu/archive.../24/95743.aspx

--
Scott
http://www.OdeToCode.com/blogs/scott/
On Fri, 29 Oct 2004 15:33:39 -0400, "Nicholas Paldino [.NET/C# MVP]"
<mv*@spam.guard.caspershouse.com> wrote:
David,

I would never implement Dispose on a struct, but I would have a struct
that has a public dispose method to do scope cleanup. For example, I have a
struct that performs an operation like a data adapter, where it will take a
connection, and if it is closed, will close it, and if open, will keep it
open. When it disposes, it will leave the connection state the way it found
it.

It is placed in a struct specifically to be used in a using statement as
a perf enhancement. Having an object do this would require the object to be
cleaned up at a later time, instead of being wiped away with the stack.


Nov 16 '05 #11
Thanks, Nicholas.

This makes perfect sense.
Nov 16 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: news.microsoft.com | last post by:
Hi, I am using structs and am also using property accessors to access those private member fields... TO me this is a good way of handling them, but I find alot of people using direct access to...
30
by: stephen henry | last post by:
Hi all, I have a question that I'm having difficulty answering. If I have a struct: typedef struct my_struct_tag{ struct my_other_struct *other; } my_struct_tag
5
by: Paminu | last post by:
Why make an array of pointers to structs, when it is possible to just make an array of structs? I have this struct: struct test { int a; int b;
10
by: Angel | last post by:
I'm using several C functions (in a dll) that receive a struct as parameter. Since I'm doing it in C#, I assume I need to recreate the struct in C# in order to call the function with the required...
5
by: Bidule | last post by:
Hi, I'm trying to sort structs defined as follows: struct combinationRec { float score; char* name; }; The number of structs and the length of the "name" field are not known
5
by: Steve Edwards | last post by:
Hi, With much help from this forum I've been using stl containers, but always with other common - or stl - types as members. I've now run in to a problem while trying to use some of my own...
14
by: Jeff S. | last post by:
In a Windows Forms application I plan to have a collection of structs - each of which contains a bunch of properties describing a person (e.g., LastName, FirstName, EmployeeID, HomeAddress,...
61
by: Marty | last post by:
I am new to C# and to structs so this could be easy or just not possible. I have a struct defined called Branch If I use Branch myBranch = new Branch(i); // everything works If I use Branch...
11
by: Cliff Martin | last post by:
Hi, I am reading a fairly large file a line at a time, doing some processing, and filtering out bits of the line. I am storing the interesting information in a struct and then printing it out....
29
by: Dom | last post by:
I'm really confused by the difference between a Struct and a Class? Sometimes, I want just a group of fields to go together. A Class without methods seems wrong, in that it carries too much...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.