Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#OOPs体系结构问题_C#_Oop_Architecture - Fatal编程技术网

C#OOPs体系结构问题

C#OOPs体系结构问题,c#,oop,architecture,C#,Oop,Architecture,在尝试使我的体系结构灵活时,我面临一个类解析问题。为了简单起见,考虑下面的例子: 我有四层:UI、BL、Common和DAL 我的BL层中有一个基类,定义如下: public class User { private UserDTO _d; public User() { _d = new UserDTO(); } public User(UserDTO d) {

在尝试使我的体系结构灵活时,我面临一个类解析问题。为了简单起见,考虑下面的例子:

我有四层:UI、BL、Common和DAL

我的BL层中有一个基类,定义如下:

public class User
    {
        private UserDTO _d;
        public User()
        {
            _d = new UserDTO();
        }
        public User(UserDTO d)
        {
            _d = new UserDTO(d);
        }
        public UserDTO D
        {
            get { return _d; }
            set { _d = value; }
        }

        //static method (I cannot make it non-static due to some reasons)
        public static User GetUser()
        {
            User user = new User(Provider.DAL.GetUser());
            return user;            
        }
    }
DTO的定义如下:

public class UserDTO
    {
        public int ID;
        public UserDTO()
        {
        }

        public UserDTO(UserDTO source)
        {
            ID = source.ID;
        }
    }
我的DAL定义为(它将数据返回给非业务对象):

现在,我想“扩展”我的代码,以便在我的用户表中还有一个字段:Name。因此,我创建了一个派生DTO类,如下所示:

 public class MyUserDTO : UserDTO
    {
    public string Name;
    public MyUserDTO()
    {
    }

    public MyUserDTO(MyUserDTO source)
    {
        Name = source.Name; //new field
        base.ID = source.ID;
    }
}
 public class MyUser : User
    {
        public MyUser()
        {
            this.D = new MyUserDTO(); 
        }
    }
然后,我创建一个派生用户类,如下所示:

 public class MyUserDTO : UserDTO
    {
    public string Name;
    public MyUserDTO()
    {
    }

    public MyUserDTO(MyUserDTO source)
    {
        Name = source.Name; //new field
        base.ID = source.ID;
    }
}
 public class MyUser : User
    {
        public MyUser()
        {
            this.D = new MyUserDTO(); 
        }
    }
我使用以下方法创建自己的自定义DAL提供程序:

 public static UserDTO GetUser()
        {
            UserDTO dto = new MyUserDTO();
            dto.ID = 99;
            ((MyUserDTO)dto).Name = "New Provider Name";
            return dto;
        }
现在,当我在BL中访问此MyUserDTO对象时,它将丢失分辨率:

User.GetUser(DAL.Provider.GetUser())

在UI中,我没有得到MyUserDTO中的属性

是否有一种方法可以帮助我在UI层中获取这些属性,即使在我调用static User.GetUser()方法(该方法将调用我的自定义提供程序并返回MyUserDTO对象)之后也是如此


谢谢,

您没有从类继承来添加新数据,只有在新类将扩展旧类的行为时,您才继承


为您的用户数据提供一个名称-值集合,以保存其数据并填充该数据。这样您就不会有问题。

您无法获得派生行为,因为用户类中的静态方法不能被MyUser类重写

您应该删除静态方法(我知道您已经指出您不能),但实际上您应该这样做


尝试在另一个对象(工厂、存储库等)中提取用户创建的内容,从我看到的看起来像User。GetUser()将返回一个User对象,而不是MyUserDTO对象,这就是为什么您无法获取这些额外字段的原因。DAL层需要遵守其所针对的合同。有几种方法可以解决这个问题,尽管有些方法比其他方法更“正确”

您可以将从User.GetUser中获取的对象强制转换为相应的对象,然后该对象将允许您访问强制转换对象的字段(假设该对象可以强制转换为该类型)。从设计的角度来看,我不太喜欢这个解决方案,但它可以工作:

MyDTOUser myDtoUser = User.GetUser() as MyDTOUser;

其他人已经发布了一些关于这种方法的其他示例,因此我在此不再重复。

正如其他人所提到的,问题在于静态方法

我还建议使用泛型或依赖项注入来清理并行对象层次结构。你不想重复

与其拥有一组几乎相同的、具有相同层次结构的“User”和“MyUser”类,不如执行类似于User的操作,并插入userdt以获得所需的类型

如果重构并删除对象层次结构重复,则可以更容易地找到解决静态GetUser()问题的好方法