Hello,
I'm still working on my self-aware classes for database communication, and I have an issue that I'd like to see clarified.
i've been reading some more about the C# programming, and came across the stuff regarding "boxing and unboxing" of variables. And if I understand that concept correctly, I think it applies to the following situation:
I have a class called Cell. It holds a string for the columnname and 2 objects for the value and the old_value.
I'm sure that if I obtain and store the data each time in these objects, I'm bound to disaster performance wise with the boxing & unboxing concept.
Is there a solution that allows me to store any kind of data in a variable without having to go around the boxing & unboxing stuff?
6 2437
I've worked around the problem by using Generics, but I think i've run into another problem now :)
Consider my class Cell : -
public class Cell<T> : ICloneable, IComparable, ISerializable, IXmlSerializable
-
{
-
#region Constructors
-
-
/// <summary>
-
/// Creates a new instance of the Cell class without setting
-
/// a name of value.
-
/// </summary>
-
public Cell()
-
: this(String.Empty, default(T))
-
{ }
-
-
/// <summary>
-
/// Creates a new instance of the Cell class with the specified
-
/// name. The value will be set to null.
-
/// </summary>
-
/// <param name="name"></param>
-
public Cell(string name)
-
: this(name, default(T))
-
{ }
-
-
/// <summary>
-
/// Creates a new instance of the Cell class with the specified name
-
/// and value.
-
/// </summary>
-
/// <param name="name">The name of the Cell.</param>
-
/// <param name="value">The raw value of the Cell.</param>
-
public Cell(string name, T value)
-
{
-
this.Name = name;
-
this.Value = value;
-
this.OldValue = default(T);
-
}
-
-
/// <summary>
-
/// Creates a new instance of the Cell class with the information
-
/// passed from the serialization context.
-
/// </summary>
-
/// <param name="info"></param>
-
/// <param name="contect"></param>
-
public Cell(SerializationInfo info, StreamingContext contect)
-
{
-
this.Name = info.GetString("Cell_Name");
-
this.Value = (T)info.GetValue("Cell_Value", typeof(T));
-
this.OldValue = (T)info.GetValue("Cell_OldValue", typeof(T));
-
}
-
-
#endregion
-
-
#region Properties
-
-
/// <summary>
-
/// Gets or sets the name of the Cell.
-
/// </summary>
-
public string Name
-
{
-
get { lock (this) { return m_name; } }
-
set { lock (this) { m_name = value; } }
-
}
-
-
/// <summary>
-
/// Gets or sets the raw value of the Cell.
-
/// </summary>
-
public T Value
-
{
-
get { lock (this) { return m_value; } }
-
set { lock (this) { this.OldValue = m_value; m_value = value; } }
-
}
-
-
/// <summary>
-
/// Gets whether the contents of this Cell have been modified since
-
/// it's creation.
-
/// </summary>
-
public bool Modified
-
{
-
get { lock (this) { return EqualityComparer<T>.Default.Equals(m_old_value); } }
-
}
-
-
/// <summary>
-
/// Gets or sets the old value of the Cell.
-
/// This function supports the NexusLink framework and should not be used/visible in your code.
-
/// </summary>
-
internal T OldValue
-
{
-
get { lock (this) { return m_old_value; } }
-
set { lock (this) { m_old_value = value; } }
-
}
-
-
#endregion
-
-
#region Private Fields
-
-
private string m_name; // The name of the Cell.
-
private T m_value; // The raw value of the Cell.
-
private T m_old_value; // The raw old value of the Cell.
-
-
#endregion
-
-
#region ICloneable Members
-
-
/// <summary>
-
/// Creates a deep copy of the current Cell by copying over
-
/// all the internal datamembers in a bit-wise fashion.
-
/// </summary>
-
/// <returns>A Clone of the current Cell with the exact same data.</returns>
-
public object Clone()
-
{
-
// Surround the function call with a lock so our datamembers cannot
-
// be changed by another thread during the copy process.
-
lock (this)
-
{
-
// To perform the deep clone operation we need a memorystream
-
// and a formatter.
-
MemoryStream sm = new MemoryStream();
-
IFormatter bf = new BinaryFormatter();
-
-
// Serialize our object into memory.
-
bf.Serialize(sm, this);
-
-
// Position the cursor in the memorystream at the beginning.
-
sm.Seek(0, SeekOrigin.Begin);
-
-
// Deserialize our object into something new.
-
Cell<T> copy = (Cell<T>)bf.Deserialize(sm);
-
-
// Release the memory.
-
sm.Close();
-
-
// Return the copy.
-
return copy;
-
}
-
}
-
-
#endregion
-
-
#region IComparable Members
-
-
/// <summary>
-
/// Compares two Cells against each other based upon their name.
-
/// </summary>
-
/// <param name="obj">The object to compare against.</param>
-
/// <returns>Less then zero if the name is less then the passed Cell's name; zero if both names are equal; Greather then zero if the name if more then the passed Cell's name.</returns>
-
/// <exception cref="ArgumentException">The object 'obj' is not of type Cell.</exception>
-
public int CompareTo(object obj)
-
{
-
// Surround the function call with a lock so our data
-
// does not get altered by another thread during the call.
-
lock (this)
-
{
-
// Convert the passed object to type Cell.
-
Cell<T> temp = obj as Cell<T>;
-
-
// First check if the passed object is of the same type.
-
if (temp == null)
-
{
-
throw new ArgumentException("The passed object 'obj' is not of type Cell");
-
}
-
-
// Cells are considered identical if there names match. Otherwise they
-
// will be sorted in order of their name.
-
return this.Name.CompareTo(temp.Name);
-
}
-
}
-
-
#endregion
-
-
#region ISerializable Members
-
-
/// <summary>
-
/// Allows the object to be serialized for transport or storage. This function stores
-
/// all the required information from the object into the SerializationInfo object.
-
/// The StreamingContext provides additional information about the destination of
-
/// the serialization.
-
/// </summary>
-
/// <param name="info">The SerializationInfo object to hold the data.</param>
-
/// <param name="context">Additional information about the destination of the serialization.</param>
-
public void GetObjectData(SerializationInfo info, StreamingContext context)
-
{
-
// Surround our call with a lock, because we don't want our
-
// data changed during the retrieval process.
-
lock (this)
-
{
-
// Add our data to the SerializationInfo object.
-
info.AddValue("Cell_Name", this.Name);
-
info.AddValue("Cell_Value", this.Value);
-
info.AddValue("Cell_OldValue", this.OldValue);
-
}
-
}
-
-
#endregion
-
-
#region IXmlSerializable Members
-
-
/// <summary>
-
/// Only used by the DataSet in .NET, therefor this function always
-
/// returns null because we're not a DataSet.
-
/// </summary>
-
/// <returns>null</returns>
-
public System.Xml.Schema.XmlSchema GetSchema()
-
{
-
return null;
-
}
-
-
/// <summary>
-
/// This function will read out the XML and rebuild the entire Cell object
-
/// based upon the information stored in the XML.
-
/// </summary>
-
/// <param name="reader">The XmlReader to parse the XML document.</param>
-
public void ReadXml(System.Xml.XmlReader reader)
-
{
-
// Consume the root element first of the XML file.
-
reader.ReadStartElement();
-
-
// Read the first attribute of the root element, this should be the name
-
// of our Cell.
-
this.Name = reader.GetAttribute("name");
-
-
// Read the value of our cell next.
-
reader.ReadStartElement("value");
-
this.Value = (T)reader.ReadContentAs(typeof(T), null);
-
reader.ReadEndElement();
-
-
// Read the old value of cell.
-
reader.ReadStartElement("oldvalue");
-
this.OldValue = (T)reader.ReadContentAs(typeof(T), null);
-
reader.ReadEndElement();
-
-
// Consume the root end tag.
-
reader.ReadEndElement();
-
}
-
-
/// <summary>
-
/// This function will write out the attributes of our class
-
/// into the XML file. Because we wish that a Cell is represented
-
/// as a single element, we will add the values as attributes.
-
/// </summary>
-
/// <param name="writer">The XmlWriter to write the XML file.</param>
-
public void WriteXml(System.Xml.XmlWriter writer)
-
{
-
// Write the name of our cell as an attribute in the root tag.
-
// We always assume the root tag to be present.
-
writer.WriteAttributeString("name", this.Name);
-
-
// Now we will write the elements to contain the values of our Cell.
-
// These will be childnodes of the Cell element.
-
writer.WriteStartElement("value");
-
writer.WriteValue(this.Value);
-
writer.WriteEndElement();
-
-
// As last step we write the "old value" of the Cell element.
-
// Just like the "value" it's a child of Cell.
-
writer.WriteStartElement("oldvalue");
-
writer.WriteValue(this.OldValue);
-
writer.WriteEndElement();
-
-
// We never write the root elements.
-
}
-
-
#endregion
-
}
-
Now I have a class Row, that holds a generic list of type Cell<T>, but I'm confused on how to properly work with or define the type T for Cell in my row. -
class Row : ICloneable, ISerializable, IXmlSerializable
-
{
-
public Row()
-
{ }
-
-
internal Row(List<Cell<Type>> cells)
-
{ }
-
-
public bool Add(Cell<Type> cell)
-
{ }
-
-
public bool Remove(Cell<Type> cell)
-
{ }
-
-
public bool Contains(Cell<Type> cell)
-
{ }
-
-
internal bool ContainsModifiedCells()
-
{ }
-
-
public Cell<Type> this[int index]
-
{
-
get{}
-
}
-
-
public Cell<Type> this[string name]
-
{
-
get{}
-
}
-
-
public int Count
-
{
-
get { lock (this) { return m_cells.Count; } }
-
}
-
-
private List<Cell<Type>> m_cells;
-
Is this correct? The compiler is not complaining, but it looks so odd and confusing....
Plater 7,872
Recognized Expert Expert
You are changing <Type> to the type you want right?
private List<Cell<Type>> m_cells;
So using the "Type" class from reflection instead of just "T" will work?
The idea is to have a list of Cell<T> objects. Each Cell in the list should be able to have a different type at runtime. That's what I'm trying to achieve. I don't want to make my Row class Generic or type bound either, I just want to be able to do this for example: -
Row r = new Row'();
-
r.AddCell(new Cell<int>("ID"));
-
r.AddCell(new Cell<string>("Name"));
-
r.AddCell(new Cell<object>("Image"));
-
r.AddCell(new Cell<int>("Amount"));
-
r.Commit();
-
That's what I'm trying to achieve, so I can reuse the single Cell class without having to worry about bocxing.unboxing values when retrieving info from the database. Hope I made it clear what I'm trying to achieve.
Plater 7,872
Recognized Expert Expert
Yeah I can see what you want, but List<Cell<Type>> will force your Cell objects to contain the Type class (or derived classes) and not Type T.
At some point I think you are going to have to box/unbox your entries if you want a collection with different types in it.
any way around the issue then?
I tried defining them it as
But this gives me compiler errors, saying something about namespace T not recognised.
Surely there must be a way to implement this without making my Row class Generic, or type bound?
Plater 7,872
Recognized Expert Expert
If it were possible, I would think there would already be a class that does it?
You've pretty much just re-created the DataRow object right now
Sign in to post your reply or Sign up for a free account.
Similar topics
by: Justine |
last post by:
Hi All,
I need a small clarification with regard to Boxing.
struct Currency
{ ......... }
Currency Bal = new Currency;
Object Obj = Bal;
|
by: ALI-R |
last post by:
Hi All,
First of all I think this is gonna be one of those threads :-) since I have
bunch of questions which make this very controversial:-0)
Ok,Let's see:
I was reading an article that When...
|
by: Ed A |
last post by:
Hi all:
I'm using a struct of type Point that is being passed on to a method as a
refrence type (boxing), the UpdatePoint method changes the coordinates of
this point as such:
Point p = new...
|
by: Peter Olcott |
last post by:
How can I create an ArrayList in the older version of .NET that does not require
the expensive Boxing and UnBoxing operations?
In my case it will be an ArrayList of structures of ordinal types.
...
|
by: ahjiang |
last post by:
hi there,,
what is the real advantage of boxing and unboxing operations in csharp?
tried looking ard the internet but couldnt find any articles on it.
appreciate any help
|
by: Peter Olcott |
last post by:
According to Troelsen in "C# and the .NET Platform"
"Boxing can be formally defined as the process of explicitly converting a value
type into a corresponding reference type."
I think that my...
|
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...
|
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...
|
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,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
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: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
| |