|
HI LookSharp, I am not sure how to use it exactly, let me try first then I will ask you later.
Thanks for your help.
|
|
|
|
|
Hi - I'm implementing a data access layer in LINQ to SQL.
I have a DataContext MyDataContext which extends DataContext.
DataContext implements IDisposable.
However when I try to put MyDataContext in a using statement I get a compiler error:
'MyDataContext':type used in a using statement must be implicitly convertible to 'System.IDisposable'.
So is IDisposable not implicitly usable for derived classes or am I doing something wrong? Here is some sample code:
using (MyDataContext context = new MyDataContext())
{
//do some work
}
|
|
|
|
|
If your class inherits from DataContext, you get IDisposable for free. Could you post your class definition here so that we can take a look at it?
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I have a class in which I have a property that returns an array of enums (which are declared in a class that is used by this class through a using statement).
When I use this class, I access the property through the indexer.
The enum and accessor look like:
enum State
{
Flashing,
Played,
NotPlayed
}
class1.balls[i] = State.Played;
Now, what I want to do is take action when the property is set through the indexer like in the example above. I want to know the value of the indexer (i) and what it is being set to.
All the internet examples I see use a separate class for this, but that doesn't make sense to me. I can't see how to make the separate class access things within the original class I have the public property in.
Thanks!
|
|
|
|
|
The C# spec has this to say about indexers:
Indexer declarations are similar to property declarations, with the main differences being that indexers are nameless (the “name” used in the declaration is this , since this is being indexed) and that indexers include indexing parameters. The indexing parameters are provided between square brackets.
edit: page 60/553 of ECMA-334 4th edition (June 2006)
Which means that you can not declare an indexer with a name, you can only use indexers to write expressions of the form instance[parameter list]
To give it a name, you have to cheat - for example by having a field (with the wanted name, of course) of a type that has an indexer. Usually, that would be a field of an other type, which you created solely to be indexed. That type should, of course, have enough information to be indexed, but you could pass in the entire "parent" instance (edit: at the ctor, when you initialize that field).
|
|
|
|
|
Arrays are way to simple a structure for what you are looking for. If you want events fired when items are added to the list, try inheriting from Collection<T> and implementing the events. e.g.[^]
|
|
|
|
|
Or he could use an indexer, as he suggested.. must simpler and faster that way
|
|
|
|
|
You do need a separate class to do what you want to do, and it needs to expose an event that the class that uses it must handle in order to respond to changes in ball states. Here's an example (compiles under VS2008):
namespace BallStateExample
{
enum State {Flashing, Played, NotPlayed}
delegate void BallStateChanged(BallStateChangedEventArgs e);
class BallStateChangedEventArgs
{
public int BallIndex { get; set; }
public State NewState { get; set; }
}
class Balls
{
private readonly State[] _balls;
public Balls(int numBalls)
{
_balls = new State[numBalls];
}
public event BallStateChanged BallStateChanged;
private void OnBallStateChanged(int index, State newState)
{
if (BallStateChanged != null)
BallStateChanged(new BallStateChangedEventArgs { BallIndex = index, NewState = newState });
}
public State this[int index]
{
get { return _balls[index]; }
set
{
_balls[index] = value;
OnBallStateChanged(index, value);
}
}
}
class BallUser
{
private const int NUM_BALLS = 42;
public BallUser()
{
Balls = new Balls(NUM_BALLS);
Balls.BallStateChanged += Balls_StateChanged;
}
private void Balls_StateChanged(BallStateChangedEventArgs e)
{
}
public Balls Balls { get; private set; }
}
}
|
|
|
|
|
Hi,
In my form based C# app, I use one (of many) option of logging/writing program steps to a text box on the form. It works ok for a while and then starts to slow down as more and more data is passed to it. Is there a way to make this more efficient ?
Thanks in advance.
|
|
|
|
|
It slows down because you've added a large amount of data to the String that it's showing you. Strings are immutable in .NET, so every time you add data to it, an entirely new string has to be created with the old data copied to it and the new data appended to the end.
The answer is simple. Don't use a TextBox. A common replacement for this particular use is a ListBox.
|
|
|
|
|
Using a textbox should work, if done correctly. A new string need not be created each time text is appended to a textbox. As Luc said, you can use AppendText to add to a textbox. Textbox probably stores the text as an array of strings (elements are probably split on newline characters), and likely has special getters and setters for the Text property (e.g., if a line was added via AppendText, then add that to the string returned from Text when the getter is called).
|
|
|
|
|
aspdotnetdev wrote: A new string need not be created each time text is appended to a textbox. As Luc said, you can use AppendText to add to a textbox
...which creates a new string... AppendText merely takes into account the current values of the Selection properties of the TextBox and replaces that text or appends text to that selection. In any case, the selected string is replaced or text is appended to the String, resulting in a new string being created and parsed when the control needs to render itself. The longer that string gets, the more time it takes to parse it and render what's visible.
aspdotnetdev wrote: Textbox probably stores the text as an array of strings
No, it doesn't. It uses a String field all the way back up it's inheritance chain.
aspdotnetdev wrote: and likely has special getters and setters for the Text property (e.g., if a line was added via AppendText, then add that to the string returned from Text when the getter is called).
Nope. If you open Reflector and lok for yourself, it's quite easy to see.
Here's the code for the Text property of the TextBox class:
Public Overrides Property [Text] As String
Get
Return MyBase.Text
End Get
Set(ByVal value As String)
MyBase.Text = value
Me.selectionSet = False
End Set
End Property
...and for AppendText (comes from TextBoxBase):
Public Sub AppendText(ByVal [text] As String)
If ([text].Length > 0) Then
Dim num As Integer
Dim num2 As Integer
Me.GetSelectionStartAndLength(num, num2)
Try
Dim endPosition As Integer = Me.GetEndPosition
Me.SelectInternal(endPosition, endPosition, endPosition)
Me.SelectedText = [text]
Finally
If ((MyBase.Width = 0) OrElse (MyBase.Height = 0)) Then
Me.Select(num, num2)
End If
End Try
End If
End Sub
There's nothing special in there.
As for WordWrap, that may or may not be a viable option depending on requirements. TextBox works with monolithic strings no matter what you do. ListBox works with an array of Objects and can handle much more of and more varied content than a TextBox can.
|
|
|
|
|
Noooooo...... Argggghhhhhh; the horror. VB.NET in a C# forum..... Please Dave, change the reflector output target before you inadvertenly trigger the destruction of the universe.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Sorry, that's the last setting I used... I'll be a little more careful with the "End of the World" next time.
|
|
|
|
|
Keep going down the chain. "MyBase.Text" is not a field... it's a property with its own logic. Also, I don't see any string concatenations in that AppendText function you posted.
|
|
|
|
|
I haven't checked myself, I was told there is a native AppendText function, so one might expect that to be called. Now the real check would be to look at its instructions, i.e. how does it avoid concatenation and quadratic behavior?
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Luc Pattyn wrote: how does it avoid concatenation and quadratic behavior
Perhaps it maintains two data structures. An array where each element holds a line in the string, and a StringBuilder to hold the text that gets appended to Text (so, the only performance hit would be when the Text property is accessed and the StringBuilder has to be serialized to a string). The array of lines would be so the textbox can be painted quickly and the StringBuilder would be so concatenations wouldn't create a performance problem.
|
|
|
|
|
In reality a StringBuilder too behaves quadratically, albeit at a lower frequency: its capacity grows by doubling its size and copying characters any time it is getting full, just like the internal arrays of Lists and other collections. So a number of strings get appended for free, then a new buffer twice the current capacity get allocated and all data copied, etc. Better than copying everything on every new line of text, but still quadratic.
While a ListBox is linear, except for the collection holding the references to the items, that too would double its capacity once in a while.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I am well aware of the performance of StringBuilder. On average, there is only O(1) operation per string append. I would be willing to bet that ListBox has the same performance. I'm guessing it maintains a list internally to store the list of list box items. Lists have the same behavior as a StringBuilder (lists use an array that doubles when capacity is exceeded, just like StringBuilder does).
|
|
|
|
|
StringBuilder.Append(string) [and TextBox.AppendText(string) as well] always copies the new characters, StringBuilder uses String.wstrcpy() to do so. OTOH ListBox.Items.Add(item) only copies a reference.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
It would still have to render that string, so it would still have to read it. It might have to perform less processing if the string was significantly longer than the viewable area, but that seems like a fringe case. Also, ListBox doesn't have the same features as a TextBox (e.g., the ability to copy all the text at once). I wouldn't base my decision on using TextBox/ListBox on performance... rather, I'd base it on the features of each.
|
|
|
|
|
I agree functionality is the determining factor, assuming performance is adequate.
The OP stated "logging" and "the textbox slowing down as text gets added" which tells me significantly more text is present than can be seen at any one point in time.
BTW: copying all text (or a contiguous block of selected lines) from a ListBox isn't hard at all; it is what I often add to a ListBox-based logging Control.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Luc Pattyn wrote: significantly more text is present than can be seen at any one point in time
I meant horizontally (i.e., each item), not vertically (all items). I was basing my performance assertion on the assumption that a render would have to be performed when each item is added, which actually may not be true now that I think about it.
Luc Pattyn wrote: copying all text (or a contiguous block of selected lines) from a ListBox isn't hard at all
Yeah, but it may not be obvious to the user. And what about modifying text? Different controls for different functionality. Anyway, my main point was that TextBox should probably suffice. The user was having problems with appending text taking more time as there was more text added, and that has nothing to do with the size of each item added to the textbox (unless the OP was adding larger and larger items). Just didn't like to see people jumping in saying to avoid TextBox like the plague. TextBox has feelings too!
|
|
|
|
|
aspdotnetdev wrote: Just didn't like to see people jumping in saying to avoid TextBox like the plague. TextBox has feelings too!
No problem. The only Controls I'm willing to disrespect are PictureBox and NumericUpDown; the former because it is only good at extremely simple things, for which I don't need a specialized Control; the latter because its arrow clicking is just awkward IMO.
TextBoxes are great, especially for displaying text that doesn't change all the time; I do prefer them in single-line mode though. And when in doubt, I'll use a ListBox, but that you knew already.
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
Keep going. It's backed by an unmanaged field buried in the Win32 Window class.
The actual value is managed by Win32, not .NET, by sending window messages like EM_SETTEXT, EM_REPLACESEL, and the like.
aspdotnetdev wrote: Also, I don't see any string concatenations in that AppendText function you posted.
I didn't say there was any.
|
|
|
|
|