Унаследованный класс болота, как сделать этот обслуживаемый код - PullRequest
1 голос
/ 27 ноября 2008

Я хочу создать обслуживаемый код, но эта ситуация наследования вызывает у меня проблемы.

Проблема связана с моим вторым вспомогательным классом базы данных с именем InitUserExtension .

Поскольку UserExtension наследуется от пользователя, я должен убедиться, что я отражает все изменения в моем помощнике InitUser для InitUserExtension.

Мне действительно не нравится это, поскольку он подвержен ошибкам, каково решение?

Мои определения классов:

public class User
{
    public string Name {get; set; }
    public string Age { get; set; }
}

public class UserExtension : User
{
    public string Lastname {get; set; }
        public string Password {get; set; }

}

Помощники моей базы данных:

public static SqlDataReader InitUser(SqlDataReader dr)
{
      User user = new User();

      user.Name = Convert.ToString(dr["name"]);
      user.Age ...
}


public static SqlDataReader InitUserExtension(SqlDataReader dr)
{
      UserExtension user = new UserExtension();


      // note: mirror attributes from User
      user.Name = Convert.ToString(dr["name"]);
      user.Age ...



      user.Lastname = Convert.ToString(dr["lastname"]);
      user.Password = ....;
}

Ответы [ 4 ]

2 голосов
/ 27 ноября 2008

Как насчет перемещения обработки Имени и т. Д. В метод (принимая пользователя или пользователя T:) и вызова этого из обоих?

private static void InitUser(User user, SqlDataReader dr)
{ // could also use an interface here, or generics with T : User
  user.Name = Convert.ToString(dr["name"]);
  user.Age ...
}


public static User InitUser(SqlDataReader dr)
{
    User user = new User();
    InitUser(user, dr);
    return user;
}

public static UserExtension InitUserExtension(SqlDataReader dr)
{
  UserExtension user = new UserExtension();
  InitUser(user, dr);
  user.Lastname = Convert.ToString(dr["lastname"]);
  user.Password = ....;
  return user;
}

В качестве альтернативы вы можете уменьшить количество строк, но увеличить сложность, используя обобщенные значения:

private static T InitUserCore<T>(SqlDataReader dr) where T : User, new()
{
    T user = new T();
    // ...
    return user;
}
public static User InitUser(SqlDataReader dr)
{
    return InitUserCore<User>(dr);
}
public static UserExtension InitUserExtension(SqlDataReader dr)
{
    UserExtension user = InitUserCore<UserExtension>(dr);
    // ...
    return user;
}
1 голос
/ 27 ноября 2008

Если вы предпочитаете помощников, делайте то же самое с помощниками

public class InitUser
{
    public InitUser(SqlDataReader dr, User u) { }
}

public class InitUserExtension : InitUser
{
    public InitUserExtension(SqlDataReader dr , UserExtension u) : base(dr, u) { }
}
1 голос
/ 27 ноября 2008

Почему бы вам не вызвать InitUser из метода InitUserExtension. Пусть базовая инициализация обрабатывает свойства базового класса, а расширенный инициализатор обрабатывает свойства расширенного класса.

0 голосов
/ 27 ноября 2008

Я не уверен, почему вы не поместили код назначения в сами классы, но это может иметь отношение к тому, как вы получаете информацию для ее хранения ...

Мое решение было бы переписать что-то вроде:

public class User
{
    public string Name {get; set; }
    public string Age { get; set; }

    public User(DataReader dr)
    {
       user.Name = Convert.ToString(dr["name"]);
       user.Age ...
    }
}

public class UserExtension : User
{
    public string Lastname {get; set; }
    public string Password {get; set; }

    public UserExtension(DataReader dr):base(dr)
    {
        user.Lastname = Convert.ToString(dr["lastname"]);
        user.Password = ....;

    }
}

Милиция может варьироваться в зависимости от ваших обстоятельств

Таким образом, звонок как

var MyExtension = new UserExtension(dr); 

заполнит все поля соответствующим образом.

...