Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.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# 不接受C中的空对象_C#_Object_Nullable_Nullreferenceexception - Fatal编程技术网

C# 不接受C中的空对象

C# 不接受C中的空对象,c#,object,nullable,nullreferenceexception,C#,Object,Nullable,Nullreferenceexception,当我运行代码时,它告诉我adr的对象为null,这是真的,但是当它在同一个方法的副本中工作时,它为什么不工作,并且执行insert而不是select 代码如下所示: public City doesExist(string postnr, string navn, City city, SqlConnection con) { DatabaseConnection.openConnection(con); using (var command = new SqlCommand("

当我运行代码时,它告诉我adr的对象为null,这是真的,但是当它在同一个方法的副本中工作时,它为什么不工作,并且执行insert而不是select

代码如下所示:

public City doesExist(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("select Id from [By] where Postnummer='" + postnr + "' and Navn='" + navn + "'", con))
    {
        command.Connection = con;
        SqlDataReader reader = command.ExecuteReader();
        if (reader.Read())
        {
            city.id = reader.GetInt32(0);
            city.postnr = postnr;
            city.navn = navn;
            reader.Close();

            return city;
        }

        reader.Close();
        return null;
    }
}

public City create(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
    {
        object ID = command.ExecuteScalar();

        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}
City city = new City();
city = city.doesExist(zip, by, city, connection); // this works fine
if (city == null)
{
     // I know that city is null
     // tried inserting City city = new City(); same error
     city = city.create(zip, by, city, connection); // this is where the null error occours
}
该呼叫如下所示:

public City doesExist(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("select Id from [By] where Postnummer='" + postnr + "' and Navn='" + navn + "'", con))
    {
        command.Connection = con;
        SqlDataReader reader = command.ExecuteReader();
        if (reader.Read())
        {
            city.id = reader.GetInt32(0);
            city.postnr = postnr;
            city.navn = navn;
            reader.Close();

            return city;
        }

        reader.Close();
        return null;
    }
}

public City create(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
    {
        object ID = command.ExecuteScalar();

        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}
City city = new City();
city = city.doesExist(zip, by, city, connection); // this works fine
if (city == null)
{
     // I know that city is null
     // tried inserting City city = new City(); same error
     city = city.create(zip, by, city, connection); // this is where the null error occours
}
是的,你看:

if (city == null)
{
    // If we've got in here, we know that city is a null reference, but...
    city = city.create(...);
}
您正在对一个绝对为空的引用调用一个方法。这保证会引发NullReferenceException

几乎可以肯定的是,您希望将create方法设置为静态,并将其重命名为符合正常的.NET命名约定,并将其称为

city = City.Create(...);
您还需要从方法调用中删除city参数,而是在方法中创建一个新的city对象。例如:

public static City Create(string postnr, string navn, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand
         ("insert into [By] (Postnummer, Navn) values (@postnr, @navn); "+
          "select @@identity as 'identity';", con))
    {
        command.Parameters.Add("@postnr", SqlDbType.NVarChar).Value = postnr;
        command.Parameters.Add("@navn", SqlDbType.NVarChar).Value = navn;
        object ID = command.ExecuteScalar();

        City = new City();
        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}
请注意,我是如何将您的代码更改为使用参数化SQL的。你真的,真的,不应该像那样把值直接放到你的SQL语句中——它会打开你的系统,使各种转换变得混乱

此外,我建议为每个数据库操作创建一个新的SqlConnection并关闭它

坦白地说,作为一种实例方法,doesExist也有点奇怪。。。同样,它需要一个城市参数

我建议更改此文件的设计,以便您有一个CityRepository或类似文件,它知道连接字符串,并公开:

// I'd rename these parameters to be more meaningful, but as I can't work out what they're
// meant to mean now, it's hard to suggest alternatives.
public City Lookup(string postnr, string nav)

public City Create(string postnr, string nav)

存储库将知道相关的连接字符串,并负责所有数据库操作。City类型对数据库一无所知。

您试图调用尚未初始化/为null的对象类上的方法

您需要创建City.create静态成员

public static City create(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
    {
        object ID = command.ExecuteScalar();

        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}
然后像这样使用它:

if(city==null) 
{
    City city = City.create(... );
}
更好的方法是:

 static public City create(string postnr, string navn, SqlConnection con)
 {
     DatabaseConnection.openConnection(con);
     using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
     {
         object ID = command.ExecuteScalar();

         City city = new City();
         city.id = Convert.ToInt32(ID);
         city.postnr = postnr;
         city.navn = navn;
         return city;
     }

     return null;
 }
Create方法必须是静态的,并且不需要在参数中包含city。 称之为:

 if (city == null)
 {
      city = City.Create(.....);
 }

为什么create方法是City类的实例方法?当然,它会抛出一个异常。毕竟,city是空的,不是吗?“Create”方法不需要是静态的吗?请注意,doesExist方法还接受一个未使用的输入city参数,应该删除它。实际上,这两种方法看起来都像存储库方法,也就是说,它们不应该是city类的实例方法,因为它们不属于单个city实例。警告:您的代码可能容易受到sql注入攻击@MichaelTotKorsgaard查看JonSkeet在下面的回答……并可能从该方法中删除city参数。+1:为了同时删除Sql注入漏洞。是否在每个方法中关闭和重新打开数据库连接都会减慢加载过程,而不是打开一个ConnectionOne,执行所有调用,然后关闭它?@MichaelTotKorsgaard:不-连接池将为您处理真正的连接,它将确保您不会在同一个连接上同时做两件事。