webForumDet fria alternativet

Abstrakt klass?

6 svar · 623 visningar · startad av Josef

JosefMedlem sedan mars 20023 561 inlägg
#1

Jag har två klasser. En BaseManager<T> och en UserManager som ärver av BaseManager.

public abstract class BaseManager<T>
    {
        public bool Create(List<SqlParameter> sqlParams, string sp)
        {
            int _rowsAffected;

            using (SqlConnection cn = DataAccess.GetConnection())
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.Connection = cn;
                    cmd.CommandText = sp;
                    cmd.CommandType = CommandType.StoredProcedure;

                    foreach (SqlParameter param in sqlParams)
                        cmd.Parameters.Add(param);

                    try
                    {
                        cn.Open();
                        _rowsAffected = cmd.ExecuteNonQuery();
                    }
                    catch (SqlException)
                    {
                        throw;
                    }
                }
            }

            return (_rowsAffected == 1);
        }
}
    class UserManager : BaseManager<User>
    {
        public override bool Create(User item)
        {
            bool _done = false;

            SqlParameter p0 = new SqlParameter("@username", SqlDbType.NChar);
            p0.Value = item.Username;

            SqlParameter p1 = new SqlParameter("@password", SqlDbType.Binary);
            p1.Value = item.Password;

            SqlParameter p2 = new SqlParameter("@email", SqlDbType.NChar);
            p2.Value = item.Email;

            SqlParameter p3 = new SqlParameter("@year_of_birth", SqlDbType.Int);
            p3.Value = item.YearOfBirth;

            SqlParameter p4 = new SqlParameter("@gender", SqlDbType.NChar);
            p4.Value = item.Gender;

            SqlParameter p5 = new SqlParameter("@country", SqlDbType.Int);
            p5.Value = item.Country;

            _done = base.Create(new List<SqlParameter>().Add(p0, p1, p2, p3, p4, p5), "sp_CreateUser");

            return _done;

        }

Men får bara felet: 'BL.UserManager.Create(BL.User)': cannot override inherited member 'BL.BaseManager<BL.User>.Create(BL.User)' because it is not marked virtual, abstract, or override.
Men det är väl precis den är? :q

Vad gör jag för fel?

PaceMedlem sedan juni 20019 024 inlägg
#2

Metoden (Create) måste också vara märkt.

emissionMedlem sedan dec. 19996 721 inlägg
#3

...som sagt. Den måste vara virtual. Skulle dock vilja föreslå att du gör en abstrakt och tom Create-metod i basklassen (som sedan "overridas") och sedan gör om den nuvarande Create-metoden till en protected-metod med annat namn (PerformCreate el. likn). De metoder du har nu gör nämligen tämligen olika saker (dessutom med helt olika parametrar. En klassisk override är alltså ändå omöjlig), vilket gör att den inte blir en logisk överladdning. Dessutom bör du antagligen inte exponera metoden som tar sql-parametrar publikt.

GladhMedlem sedan maj 20012 812 inlägg
#4

Det finns en liten skillnad mellan en virtuell och abstrakt metod i din basklas..

Det är att om du gör din metod abstrakt så måste dina klasser som ärver från denna klass implementera sin egen metod som alltid kommer att användas (även från din basklass), du kan dessutom inte skriva någon kodlogik i din metod i basklassen, vilket är naturligt eftersom den aldrig kommer exekveras.

Om du istället väljer att skriva din basklass metod som virtuell så betyder det att du ger dina klasser som ärver från basklassen en möjlighet att själv implementera sin egen kod. Men om de klasser inte gör det så kommer basklassens metod och kod att exekveras.

En liten men ack så viktigt skillnad...

- M

JosefMedlem sedan mars 20023 561 inlägg
#5

emission: Nej, all kod du ser blir ett underliggande datalager som inte kommer att exponeras.

Gladh: Skillnaderna kände jag till. :)

Tack för hjälpen! Fungerar som det ska dock med lite mer kod. ;)

emissionMedlem sedan dec. 19996 721 inlägg
#6

Bra!

Antar att du gjorde något i stil med det jag försökte förklara, men jag passar ändå på att visa med kod.

public abstract class BaseManager<T>
{
	public abstract bool Create(T item);

	protected bool PerformCreate(List<SqlParameter> sqlParams, string sp)
	{
	    //Databaskod
	}
}

public class UserManager : BaseManager<User>
{
	public override bool Create(User item)
	{
	    //Preparera parametrar

	    _done = base.PerformCreate(new List<SqlParameter>().Add(p0, p1, p2, p3, p4, p5), "sp_CreateUser");

	    return _done;

	}
}

PS. Det är inte så bra att kalla SP:ar för sp_xxx i SQL Server, eftersom det är lite halvreserverat och gör att namnuppslaget tar längre tid. DS

JosefMedlem sedan mars 20023 561 inlägg
#7

Jag gjorde precis så. :) Men tack iaf.

Jasså? Uppslaget tar längre tid? Då får jag ändra.

PS. Erkänn du bara ville få 5300 inlägg? ;) Jämnt och bra

132 ms totalt · 3 externa anrop · v20260731065814-full.fb544a5a
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)