unboxing problem

  • Thread starter Thread starter tshad
  • Start date Start date
T

tshad

I am trying to test if my object is a TextBox and I tried:

if (messageOut is TextBox)

But I get an error message:

The type or namespace name 'TextBox' could not be found (are you missing a
using directive or an assembly reference?)

What would I be missing?

Thanks,

Tom
 
tshad said:
I am trying to test if my object is a TextBox and I tried:

if (messageOut is TextBox)

But I get an error message:

The type or namespace name 'TextBox' could not be found (are you missing a
using directive or an assembly reference?)

What would I be missing?

A using directive or an assembly reference, as it suggests. Is this a
WinForms app or a web app? What using directives do you have at the top
of your file?
 
tshad said:
I am trying to test if my object is a TextBox and I tried:

if (messageOut is TextBox)

But I get an error message:

The type or namespace name 'TextBox' could not be found (are you missing a
using directive or an assembly reference?)

What would I be missing?

What I am trying to do is take an object and write to that object. The
object could be a TextBox, Label, String, etc. The error message makes no
sense. It knows about the TextBox type as I can do:

public static void Write(TextBox messageOut,string text)
{
messageOut.Text += text;
}

And this works fine.

I want to change it to something like:

public static void Write(object messageOut,string text)
{
if (messageOut is TextBox)
{
(TextBox)message.Text += text;
}
if (messageOut is String)
{
(String)message += text;
}
}

Thanks,

Tom
 
tshad said:
I am trying to test if my object is a TextBox and I tried:

if (messageOut is TextBox)

But I get an error message:

The type or namespace name 'TextBox' could not be found (are you missing a
using directive or an assembly reference?)

What would I be missing?

I have my using clauses as:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Drawing;
using System.Text;
using System.IO;
using System.Collections;
using System.Windows.Forms;


Thanks,

Tom
 
Jon Skeet said:
A using directive or an assembly reference, as it suggests. Is this a
WinForms app or a web app? What using directives do you have at the top
of your file?

Found it.

Apparently, I needed the System.Windows.Forms as a using statement (which it
was) but I was missing the reference.

Thanks,

Tom
 
Peter said:
Well, it would have made sense if you'd shown us the lines of code
causing it. Instead, you showed us a line that most likely compiles
just fine, given your follow-up post.

I believe the problem you're having is with these two:


With the first, you can fix the error by casting correctly:

((TextBox)message).Text += text;

With the second, there is no correct line of code that is equivalent,
as strings are immutable.

It _looks_ like you are trying to accomplish something along the
lines of a TraceListener, TextWriter, etc. If so, you should
implement concrete versions of those classes that encapsulate the
underlying behavior you want. Then you would call the appropriate
methods on those objects, which would then already know exactly how
to modify the underlying object that should receive the new text.

Without knowing more about exactly what you're trying to do, it's
hard to suggest something specific.

What I am doing is creating a Log class to allow me to write to different
type of objects (TextBoxes, Labels, Strings etc). As another type comes up
I would just add it in.

In my example, I have one function (Write) that just adds a variable number
of strings to some object. The first parameter will always be the object I
am writing to.

********************************************
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;

namespace RepositoryServiceApp.BusinessLayer
{
public class Log
{

public static void Write(params object[] names)
{
object destination = null;

foreach (object name in names)
{
if (destination == null)
{
destination = name;
}
else
{
if (name is string)
{
if (destination is TextBox)
{
((TextBox)destination).Text += (string)name;
}
if (destination is Label)
{
((Label)destination).Text += (string)name;
}
if (destination is string)
{
destination += (string)name;
}
}
}
}
}
public static void Write(object messageOut,string text)
{
}
}
}

********************************************

Then I could call it like so, where Status could be a TextBox or a string):

Log.Write(Status, parameter.ParameterName,"
",parameter.SqlDbType.ToString()," ",stemp,Environment.NewLine);

This seems to work pretty well.

I could also set up set a variable at the top of the program:

static object statusOutput = null;

Then later in my code I could set statusOutput to what ever I wanted:
Status(TextBox), stemp (string), etc and call it like so:

Log.Write(statusOutput, stext1," ",stext2,"
",stemp,Environment.NewLine);

This would allow me to use the same code to write status information to a
Multiline TextBox or a strint, or something else by just changing the
statusOutput at the top of the program.

Thanks,

Tom
 
Peter said:
Well, the usual way to do this is to create a specific concrete class
inheriting a class like TraceListener or TextWriter, one for each
kind of target class. Then each concrete class would already have
all the correct type information and you wouldn't need to cast
anything.

Not sure how I would do that or why if most of the time I am dealing only
with a string or textboxes and labels for this. But I will be using other
objects later.
An alternative might be to have a single class that requires the
passing in of a delegate that takes as the parameter a string, and
then which outputs that string to whatever is appropriate for the
code creating an instance of the logging class using the delegate. This is
more general purpose and avoids having to create a new class
for each possible output target type. But it would mean you'd have
to at least declare a delegate method for each possible output target
type.
You can do it using the kind of code you've posted (except having
fixed the problems, of course...even the new code you posted still
has the problem that your code assumes strings are mutable when they
aren't). But I think it's a poor design choice to have an "if/else
if" block testing the type and executing special code for each type.
You're right, of course.

I tried it out with the string as so:

string stemp = null;

Log.Write(stemp, "a test", " to see", " if this", " would
work");
Log.Write(stemp, " or not.", " What do you", " think?");
string stemp2 = stemp;

but stemp and stemp2 were both null at the end.

Textboxes and Labels work fine though.

I guess I could return the object, but then I would have to cast it. This
would nullify the point of doing it this way so that I can just define the
output as an object and then just pass in whatever type of object I want and
have the Write method handle the differences. It works great for Textboxes
and Labels as I mentioned, but then there's that pesky string :(

Why is the if/else testing of the type a bad design - I agree that if/else
better than my multiple ifs.
At the very least, you need to fix the problem with the string as
output, and you should really be using "if/else if" instead of
repeated "if" statements. It's not likely to cause a real
performance problem the way it is, but it's unnecessarily wasteful
anyway.
I agree on that.

This was just the first pass.

I had thought about using a switch statement, but not sure if you can since
I am not testing a type and not a value.

Thanks,

Tom
 
As already mentioned, you can't write to strings. You can't change strings
in any way. Use a StringBuilder instead, which has an append method.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top