473,395 Members | 1,460 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,395 software developers and data experts.

How to making a read-only array reference?

Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking. I have been trying to use Array.AsReadOnly()
to return a read only reference, but with very little success:

public class Foo {

private byte[] m_bytes;

public Foo() { m_bytes = new byte[] { 0x00, 0x01, 0x02 }; }

public byte[] Bytes {
get { return Array.AsReadOnly(m_bytes); }
set { /* error checking omitted */ m_bytes = value; }
}
}

This gave a compile time error:

Cannot implicitly convert type
'System.Collections.ObjectModel.ReadOnlyCollection <byte>' to 'byte[]'

Trying an explicit conversion didn't work either, nor did
AsReadOnly<byte>() with or without explicit conversion.

My next effort looked like:

get {
IList<bytetemp = Array.AsReadOnly<byte>(m_bytes);
return (byte[])temp;
}

This compiled fine but threw a runtime error:

Unable to cast object of type
'System.Collections.ObjectModel.ReadOnlyCollection `1[System.Byte]' to
type 'System.Byte[]'.

Changing IList to List just gave a compile time error.

For the moment I am creating a cloned copy of the arrray and returning
that, but it is not an ideal solution as the users can amend the
cloned copy and get unexpected results when my class uses the
unchanged original. Is there anything better I could do to get a read
only array reference?

Thanks,

rossum

Aug 20 '06 #1
7 16086
rossum wrote:
Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking.
No, you can't do that. You should use a collection class instead, such
as Collection<T(in .NET 2) or CollectionBase. These classes have
indexers to make them look more like arrays. The reason arrays aren't
recommended as properties in the Design Guidelines is for precisely the
problems you're finding now.

-- Barry

--
http://barrkel.blogspot.com/
Aug 20 '06 #2
How is the user interacting with the array? If they don't need the
entire array, you could give them access to one element at a time
through a read-only property. If they are utilizing the entire array
through controls, then maybe those controls can restrict the
modifications. I like your idea of using a cloned copy - but you might
want to add some messaging to the user that changes may not be accepted
by the application. And you could add some kind of validation to see if
maybe you actually do want to accept the changes.

T

rossum wrote:
>Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking. I have been trying to use Array.AsReadOnly()
to return a read only reference, but with very little success:

public class Foo {

private byte[] m_bytes;

public Foo() { m_bytes = new byte[] { 0x00, 0x01, 0x02 }; }

public byte[] Bytes {
get { return Array.AsReadOnly(m_bytes); }
set { /* error checking omitted */ m_bytes = value; }
}
}

This gave a compile time error:

Cannot implicitly convert type
'System.Collections.ObjectModel.ReadOnlyCollectio n<byte>' to 'byte[]'

Trying an explicit conversion didn't work either, nor did
AsReadOnly<byte>() with or without explicit conversion.

My next effort looked like:

get {
IList<bytetemp = Array.AsReadOnly<byte>(m_bytes);
return (byte[])temp;
}

This compiled fine but threw a runtime error:

Unable to cast object of type
'System.Collections.ObjectModel.ReadOnlyCollectio n`1[System.Byte]' to
type 'System.Byte[]'.

Changing IList to List just gave a compile time error.

For the moment I am creating a cloned copy of the arrray and returning
that, but it is not an ideal solution as the users can amend the
cloned copy and get unexpected results when my class uses the
unchanged original. Is there anything better I could do to get a read
only array reference?

Thanks,

rossum
Aug 20 '06 #3
Rossum... C# does not offer the equivalent of C++ const on a pointer.
You can
instead wrap the private array in an instance of an immutable class and
pass a
reference to the immutable wrapper object to as many clients as you
wish. You
can provide a get only indexer to the wrapper class using the syntax:

public someType this[int index]
{
get
{
...
}
}

Regards,
Jeff
>For the moment I am creating a cloned copy of the arrray and returning
that, but it is not an ideal solution as the users can amend the
cloned copy and get unexpected results when my class uses the
unchanged original.<

*** Sent via Developersdex http://www.developersdex.com ***
Aug 20 '06 #4
On Sun, 20 Aug 2006 20:19:49 +0100, rossum <ro******@coldmail.com>
wrote:
>Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking. I have been trying to use Array.AsReadOnly()
to return a read only reference, but with very little success:
RTFMSDNLibrary. AsReadOnly does not return an array, it returns a
ReadOnlyCollection<T>. That does work and gives you a read-only
collection... however, it's not an array. .NET does not support
read-only arrays, unfortunately.
--
http://www.kynosarges.de
Aug 21 '06 #5
On Sun, 20 Aug 2006 20:19:49 +0100, rossum <ro******@coldmail.com>
wrote:
>Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking. I have been trying to use Array.AsReadOnly()
to return a read only reference, but with very little success:

public class Foo {

private byte[] m_bytes;

public Foo() { m_bytes = new byte[] { 0x00, 0x01, 0x02 }; }

public byte[] Bytes {
get { return Array.AsReadOnly(m_bytes); }
set { /* error checking omitted */ m_bytes = value; }
}
}

This gave a compile time error:

Cannot implicitly convert type
'System.Collections.ObjectModel.ReadOnlyCollectio n<byte>' to 'byte[]'

Trying an explicit conversion didn't work either, nor did
AsReadOnly<byte>() with or without explicit conversion.

My next effort looked like:

get {
IList<bytetemp = Array.AsReadOnly<byte>(m_bytes);
return (byte[])temp;
}

This compiled fine but threw a runtime error:

Unable to cast object of type
'System.Collections.ObjectModel.ReadOnlyCollectio n`1[System.Byte]' to
type 'System.Byte[]'.

Changing IList to List just gave a compile time error.

For the moment I am creating a cloned copy of the arrray and returning
that, but it is not an ideal solution as the users can amend the
cloned copy and get unexpected results when my class uses the
unchanged original. Is there anything better I could do to get a read
only array reference?

Thanks,

rossum
Thanks for all your replies. I rather suspected that this was not
possible in C# and you have confirmed it. I will probably stick with
returning a cloned copy.

rossum

Aug 21 '06 #6

rossum wrote:
Is there any way of creating a read only reference to an array? My
class includes a private array of bytes with a Property to access it.
However, I do not want users to use the returned reference to modify
the array; modifications are only allowed through the property, which
includes error checking. I have been trying to use Array.AsReadOnly()
to return a read only reference, but with very little success:
It's simpler than you think. The property accessor you are using allows
you to return the array element using get{}. For a read-only property,
simply do not implement a set{}. When you do this, the array reference
in _myObjects cannot be changed outside the class, under any
circumstances. Simply create an indexed property.

For example:

class MyClass {

private Object[] _myObjects;

public Object MyObjects[N]
{
get{
return _myObjects[N];
}
}

}

class myProgram
{

public static void main(string args[])
{
MyClass newClass;
Object propertyObject;

//This generates a read-only compile error
newClass.MyObjects[0] = new Object();

//This compiles successfully
propertyObject = newClass.MyObjects[0];

//You can then access public members of this object reference as
long as they aren't read-only themselves
propertyObject.SomeProperty = someValue;

//re-initializing this variable does not change the _myObjects[]
array
propertyObject = new Object();

}
}

The get{} method can also be used to expand the array (such as adding
an index that does not yet exist). Simply add code that checks the
index passed, and if it's greater than the max index of the current
array, resize the array to add a new Object() instance and return the
newly instantiated object. This way, the caller doesn't even have to
know how to use myClass to add lines.

If you want to be able to remove an index and resize the array from
outside the class, the safest method is to implement a function that
takes the index and rearranges the array without that index.
Re-initializing an indexed object would be similar. The cases I'm
working with don't require such functionality. If you do this, to make
the interface consistent I would not allow the getter to expand or add
to the array: instead I would implement an AddIndex() function of some
sort.

Aug 21 '06 #7
On 21 Aug 2006 08:41:04 -0700, li****@gmail.com wrote:
>It's simpler than you think. The property accessor you are using allows
you to return the array element using get{}. For a read-only property,
simply do not implement a set{}. When you do this, the array reference
in _myObjects cannot be changed outside the class, under any
circumstances. Simply create an indexed property.
That works in Visual Basic but not in C#. C# only supports a single
indexed property per class, namely "this". Moreover, your "[N]"
syntax is completely unsupported in C#.

Tip: try compiling code snippets before posting them... your code
results in a screenfull of errors.
--
http://www.kynosarges.de
Aug 22 '06 #8

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

Similar topics

8
by: McGrull | last post by:
Sorry for my question, but I'm really a newbie on ASP. I need to make a simple page (for IIS 5.0 and up, but even for 2000 Professional IIS) that read and display the files contained in a...
26
by: Alexander Farber | last post by:
Hi, I have a UNIX-server written in C, which exchanges messages with Java clients. In the message the 1 byte is its length, the 2nd a player number and the 3rd byte is an event id: /* 0....
6
by: mt404 | last post by:
Hi, I was wondering if someone might be able to provide some guidance on how I could make an http request from a C# library. Basically I have a library which accepts a couple of arguments that...
5
by: Charlie | last post by:
Hi: I'm working on an e-commerce site. Using the SMTP class, my site sends out confirmation messages. It works most of the time, but sometimes raises an error. I need a way of making sure it...
0
by: Mike Cox | last post by:
Hi. As most of you know, comp.databases.postgresql.general is a wonderful resource. What you may not know is that it has not gone through a process that would enable it to be listed on hundreds...
351
by: CBFalconer | last post by:
We often find hidden, and totally unnecessary, assumptions being made in code. The following leans heavily on one particular example, which happens to be in C. However similar things can (and...
4
by: ShieldsJared | last post by:
Im looking for help making a good GUI out of pure images. I would like to embed the common controls and such, but I want to make a nice looking GUI, similar to that of, say Windows Media Player. ...
9
by: SzH | last post by:
Is it possible for a constructor to know if the object has been initialised as a 'const' ot not? The example at at end of the message illustrates what I would like to do. I want to allow...
1
by: getelectronic | last post by:
Hi all I have a sample code to implement opc client in Python. i use a file .py making by makepy with pythonwin for Com Interface. i can get all server in machine, connect to server opc,...
11
by: Rafe | last post by:
Hi, I'm working within an application (making a lot of wrappers), but the application is not case sensitive. For example, Typing obj.name, obj.Name, or even object.naMe is all fine (as far as...
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:
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
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.