Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with implementing Generics

Status
Not open for further replies.

threexmods

Programmer
Oct 23, 2007
6
GB
Hi I wonder if somebody could point me in the right direction with this problem?

I've got the follow class, which is using an object as a paramter in order to represent a variety of types, in this example ints and datetimes.

Code:
public class MyClass
{
    private object _value;

    public MyClass(object value)
    {
        _value = value;
    }

    public override string ToString()
    {
        if (_value is int)
        {
            return string.Format("{0}", _value);
        }
        if (_value is DateTime)
        {
            return string.Format("'{0}'", ((DateTime)_value).ToString("dd MMM yyyy HH:mm:ss"));
        }
    }
}

Could somebody tell me if this is a good candidate to be moved to used generics types, so that I can avoid boxing / unboxing during the casting that is going on in the ToString method.

As you can see I'm using a generic parameter for the class but the tostring method needs to convert it to a certain type in order to format the return string value.

Can anybody give me any pointers....

Thanks, Mark
 
Hopefully this is close to what you're looking for:

Code:
public class MyClass
{
	public static void Main()
	{
		MyClass<DateTime> ex1 = new MyClass<DateTime>(new DateTime(1956, 11, 4));
		MyClass<string> ex2 = new MyClass<string>("Graeme");
		MyClass<int> ex3 = new MyClass<int>(5);
		
		Console.WriteLine(ex1.ToString());
		Console.WriteLine(ex2.ToString());
		Console.WriteLine(ex3.ToString());
		
		RL();
	}
	

	#region Helper methods

	private static void WL(object text, params object[] args)
	{
		Console.WriteLine(text.ToString(), args);	
	}
	
	private static void RL()
	{
		Console.ReadLine();	
	}
	
	private static void Break() 
	{
		System.Diagnostics.Debugger.Break();
	}

	#endregion
}

public class MyClass<T>
{
    private T _value;

    public MyClass(T value)
    {
        _value = value;
    }

    public override string ToString()
    {
		return string.Format("{0}", _value.ToString());
    }
}

Hope this helps,

Graeme

"Just beacuse you're paranoid, don't mean they're not after you
 
Hi Graeme, thanks for the reply,

When I was investigating this issue, I kind of got to the same point as your class.

the problem I encountered was in the ToString method where I have to cast the generic type, _value, to a datetime in order to format the string that represents the date correctly.

Code:
return string.Format("'{0}'", ((DateTime)_value).ToString("dd MMM yyyy HH:mm:ss"));

I get the error message that I cannot convert type T to datetime...

Has anybody got any guidance as to how to achive this?

Thanks, Mark
 
I think that wasn't a good example of how to do it.

By the way I think your class is bad design. You need two classes. I think MadJock's example doesn't cover everything you have.

I think you need to look at the decorator pattern.

Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
Hi Christaan,

thanks for the reply, is this the kind of thing that could be solved using inheritance?

Splitting the very different behavior into an abstract parent class and two subclasses classes, one for the int and another to deal with the datetime ?

the individual classes would then be able to do the right thing in the overridden tostring method.

thanks for the help, Mark

 
Mmm, it depends on what MyClass is doing. Why do you need two ToString why does one get an int and the other a datetime? When are you using the one and when the other?

AS far as I can see they don need to inherit from an abstract class. But there could be more toit then I can see. BTW ToString is alread implemented by Object so it is just overriding that and that's why I don't see a need for another abstract class in this case since object is your abstractt class.

Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
Hi Christaan, you're correct the actual implementation is more complex than the example.

Basically, I have a class that represents part of a 'filter' that is to be applied to a sql server where clause. In this case the value that is to be used against a certain field.

So if the user creates a filter for a int based field then propeties are set against the integer filter value class and the ToString returns the actual formatted value that will be used

The value returned from the ToString for the date class has to be in a certain format that will be applied to the filter. We also need to escape any quotes in string based fields.

so we are kind of doing this ;

MyInt = FilterIntegerValue(12) ;

this would return the value of '12'

with the dates we do something like

MyDateFilterValue = FilterDateTimeValue(Datetime.now);

this would return a date in a certain format , ie "dd MMM yyyy HH:mm:ss" that is suitable for use against the database backend regardless of the current datetime culture settings in .net

At the moment, the datetime is the only field type that needs some specific processing other than a simple tostring method call.

I'm not sure I've described this too well!

I see you point about the abstract class.

Thanks ,Mark





 
Mmm.

So you need the ToString because you are concatenating the value in the sql-where clause, right?

Hence the need to escape quotes and put the datetime in a certain format. Right?




Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
Hi Christaan,

Yes, that's right, we also need to some processing of other datatypes when we call ToString to ensure that the resultant string is in the correct format to form part of the where clause...

I think you helped me see the basic mistake where I had one class that exhibited different behavour that really meant it should have been split into different classes....

Thanks, Mark
 
I think you have a bigger misstake. You should use parameter and not worry about all this. Trust me you are on the wrong path.

Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
If you were on vs 2008 you could use extension methods like the following. How nice is this.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestExtensionMethods
{
static class Program
{
static void Main(string[] args)
{

string s = "hello world";
s.ToSqlString();

DateTime dt = DateTime.Now;
dt.ToSqlString();

int number = 3;
number.ToSqlString();

}

static void ToSqlString(this string s)
{
Console.WriteLine(s);
}

static void ToSqlString(this DateTime s)
{
Console.WriteLine(string.Format("'{0}'",s.ToShortDateString()));
}

static void ToSqlString(this int s)
{
Console.WriteLine(s.ToString());
}
}
}
 
That's a nice 2008 enhancement,

Christiaan, thanks for all your help..I appreciate it..

I'm not sure what you mean by using parameters? I need to create a class that behaves in a similar fashion to the TestExtensionMethods example that stsuing demonstrated..any pointers?

Thanks Mark
 
I think you are doing what you are doing because you are doing this

strsql = "select * from table where field1 = " + value1

Right

I would suggest

strsql = "select * from table where field1 = @field1"

That way you don't have to escpe the single quotes you don't have to care about the format of a date and you don't have to care about sql-injection.

I'm doing a lot of guesswork here so more information is needed.

So I could be wrong and you could be doing something else.

Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top