简体   繁体   English

为什么在我的工厂模式实现c#中得到NullReferenceException?

[英]Why do I get NullReferenceException in my factory pattern implementation, c#?

Main class: 主班:

public class ClP_Login
{
    private Form vrcView;
    private I_Repository<I_Identifiable> vrcRepository = null;

    public ClP_Login(Form vrpView)
    {
        vrcView = vrpView;
        SetTheme();
    }

    private void SetTheme()
    {
        if(vrcView !=null)
        vrcView.BackColor = Cl_BaseColor.StandardBackground;
    }

    public void CreateNewUser()
    {
        ClE_User test = new ClE_User();
        test.Name = "test name";
        test.Password = "";
        Cl_RepositoryFactory vrlFactory = new Cl_RepositoryFactory();
        vrcRepository = vrlFactory.CreateRepository(E_Repositories.User);
        vrcRepository.Add(test);
    }
}

Cl_RepositoryFactory class: Cl_RepositoryFactory类:

public class Cl_RepositoryFactory
{
    public virtual I_Repository<I_Identifiable> CreateRepository(E_Repositories vrpRepository)
    {
        I_Repository<I_Identifiable> vrlRepository = null;
        switch (vrpRepository)
        {
            case E_Repositories.User:
                vrlRepository = new Cl_UserRepository() as I_Repository<I_Identifiable>;
                break;
        }
        return vrlRepository;
    }
}

Enum E_Repositories: 枚举E_Repositories:

public enum E_Repositories
{
    User
}

I_Identifiable Interface: I_Identifiable接口:

public interface I_Identifiable
{
    int Id { get; set; }
}

I_Repository Interface: I_Repository接口:

public interface I_Repository<T>
{
    T GetById(Guid id);
    T GetByQuery(Queue query);
    void Add(T item);
    void Remove(T item);
    void Update(T item);
}

Cl_UserRepository class: Cl_UserRepository类:

public class Cl_UserRepository : I_Repository<ClE_User>
{
    public void Add(ClE_User item)
    {
        MessageBox.Show("Created new User");
    }

    public ClE_User GetById(Guid id)
    {
        throw new NotImplementedException();
    }

    public ClE_User GetByQuery(Queue query)
    {
        throw new NotImplementedException();
    }

    public void Remove(ClE_User item)
    {
        throw new NotImplementedException();
    }

    public void Update(ClE_User item)
    {
        throw new NotImplementedException();
    }
}

And ClE_User class: 和ClE_User类:

public class ClE_User : I_Identifiable
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }
}

The question is, why do I get null reference exception using vrcRepository? 问题是,为什么使用vrcRepository会得到空引用异常? vrlFactory.CreateRepository(E_Repositories.User); vrlFactory.CreateRepository(E_Repositories.User); return null and I don't have any idea why, please help 返回null并且我不知道为什么,请帮助

In CreateRepository method try to remove casting statement as I_Repository<I_Identifiable> . CreateRepository方法中,尝试将强制转换语句删除as I_Repository<I_Identifiable> If your code will not compile, that will mean Cl_UserRepository is not compatible with I_Repository<I_Identifiable> . 如果您的代码无法编译,则意味着Cl_UserRepositoryI_Repository<I_Identifiable>不兼容。

Otherwise everyting is correct with CreateRepository method 否则,使用CreateRepository方法的所有设置都是正确的

ClE_User inherits from I_Identifiable , but I_Repository<ClE_User> does not inherit from I_Repository<I_Identifiable> . ClE_User继承自I_Identifiable ,但I_Repository<ClE_User>不继承自I_Repository<I_Identifiable> Those are different interfaces as far as C# is concerned. 就C#而言,这些是不同的接口。

To elaborate more, you have I_Repository<I_Identifiable> vrcRepository which should in theory take I_Repository of any I_Identifiable kind. 更详细地说明,你有I_Repository<I_Identifiable> vrcRepository理论上应该采取I_Repository任何I_Identifiable样。 So let's say you initialize this member to some other, for instance I_Repository<ClE_SomethingOtherThanUser> . 假设您将该成员初始化为其他成员,例如I_Repository<ClE_SomethingOtherThanUser> But then you call vrcRepository.Add(test) . 但是随后您调用vrcRepository.Add(test) That's not going to work, with test being ClE_User . 那是行不通的, testClE_User

Now, first remove the as I_Repository<I_Identifiable> part, and then to make it compile make I_Repository just a plain dumb non-generic interface, whose methods take I_Identifiable parameter or return I_Identifiable value. 现在,首先删除as I_Repository<I_Identifiable>部分,然后对其进行编译,使I_Repository只是一个普通的非常I_Repository通用接口,其方法采用I_Identifiable参数或返回I_Identifiable值。 This may not be what you wanted, but it will compile. 这可能不是您想要的,但是它将进行编译。

EDIT 编辑

I realize that the enum will trigger. 我意识到枚举将触发。 You are right 你是对的

new Cl_UserRepository() as I_Repository 新的Cl_UserRepository()作为I_Repository

CL_UserRepository has to implement the interface you are trying to return, and then you don't need to type cast it at all. CL_UserRepository必须实现您要返回的接口,然后根本不需要键入强制转换。 Sorry! 抱歉! I owe you a case of beer. 我欠你一箱啤酒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM