2012-02-06 23 views
23

Possible Duplicate:
c# why cant a nullable int be assigned null as a valuenull DateTime dönüştürme

Im benim okuyucu dönüştürmeye çalışırken [3] orada Forum için hiçbir lastPostDate ama Im bir dönüşüm eksik diyorsa boş olması datetime olan nesne. Hata: Aşağıda

Type of conditional expression cannot be determined because there is no implicit conversion between <null> and 'System.DateTime'

public class Forums 
{ 
    public List<Forum> GetForums() 
    { 
     using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CMS"].ConnectionString)) 
     { 
      conn.Open(); 
      SqlCommand cmd = new SqlCommand("sproc_Forums_GetForums", conn); 
      cmd.CommandType = CommandType.StoredProcedure; 
      SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default); 

      List<Forum> forums = new List<Forum>(); 
      while (reader.Read()) 
      { 
       var title = reader[6].ToString(); 
       var threadCount = (int)reader[5]; 
       var lastPostTitle = reader[4].ToString(); 
       // below is where im having a problem 
       Nullable<DateTime> lastPostDate = (reader[3] == DBNull.Value ? null : Convert.ToDateTime(reader[3])); 
       var lastPostBy = reader[2].ToString(); 
       var forumGroup = reader[1].ToString(); 
       var description = reader[0].ToString(); 

       Forum forum = new Forum(0, "",DateTime.Now, 
        reader["Title"].ToString(),description, 
        0,false,"","",DateTime.Now,true, 
        forumGroup, (int)threadCount, lastPostBy, 
        lastPostDate, lastPostTitle); 
       forums.Add(forum);/**/ 

      } 
      return forums; 

     } 

    }    
} 

bir null lastPostDate

public class Forum 
{ 
    public Forum(int forumID, string addedBy, DateTime addedDate, string title, string description, int parentID, bool moderated, 
     string imageUrl, string updatedBy, DateTime? updatedDate, bool active, string forumGroup, int threadCount, string lastPostBy, 
     Nullable<DateTime> lastPostDate, string lastPostTitle) 
    { 
     this.ForumID = forumID; 
     this.AddedBy = addedBy; 
     this.AddedDate = addedDate; 
     this.Title = title; 
     this.Description = description; 
     this.ParentID = parentID; 
     this.Moderated = moderated; 
     this.ImageUrl = imageUrl; 
     this.UpdatedBy = updatedBy; 
     this.UpdatedDate = updatedDate; 
     this.Active = active; 
     this.ForumGroup = forumGroup; 
     this.ThreadCount = threadCount; 
     this.LastPostBy = lastPostBy; 
     this.LastPostDate = lastPostDate; 
     this.LastPostTitle = lastPostTitle; 
    } 

    private int _forumID; 
    public int ForumID 
    { 
     get { return _forumID; } 
     set { _forumID = value; } 
    } 
    private string _addedBy; 
    public string AddedBy 
    { 
     get { return _addedBy; } 
     set { _addedBy = value; } 
    } 
    private DateTime _addedDate = DateTime.Now; 
    public DateTime AddedDate 
    { 
     get { return _addedDate; } 
     set { _addedDate = value; } 
    } 
    private string _title = ""; 
    public string Title 
    { 
     get { return _title; } 
     set { _title = value; } 
    } 
    private string _description = ""; 
    public string Description 
    { 
     get { return _description; } 
     set { _description = value; } 
    } 
    private int _parentID = 0; 
    public int ParentID 
    { 
     get { return _parentID; } 
     set { _parentID = value; } 
    } 
    private bool _moderated = false; 
    public bool Moderated 
    { 
     get { return _moderated; } 
     set { _moderated = value; } 
    } 
    private string _imageUrl = ""; 
    public string ImageUrl 
    { 
     get { return _imageUrl; } 
     set { _imageUrl = value; } 
    } 
    private string _updatedBy = ""; 
    public string UpdatedBy 
    { 
     get { return _updatedBy; } 
     set { _updatedBy = value; } 
    } 
    private DateTime? _updatedDate = null; 
    public DateTime? UpdatedDate 
    { 
     get { return _updatedDate; } 
     set { _updatedDate = value; } 
    } 
    private bool _active = false; 
    public bool Active 
    { 
     get { return _active; } 
     set { _active = value; } 
    } 
    private string _forumGroup = ""; 
    public string ForumGroup 
    { 
     get { return _forumGroup; } 
     set { _forumGroup = value; } 
    } 
    private int _threadCount = 0; 
    public int ThreadCount 
    { 
     get { return _threadCount; } 
     set { _threadCount = value; } 
    } 
    private string _lastPostBy = ""; 
    public string LastPostBy 
    { 
     get { return _lastPostBy; } 
     set { _lastPostBy = value; } 
    } 
    private Nullable<DateTime> _lastPosteDate = null; 
    public Nullable<DateTime> LastPostDate 
    { 
     get { return _lastPosteDate; } 
     set { _lastPosteDate = value; } 
    } 
    private string _lastPostTitle = ""; 
    public string LastPostTitle 
    { 
     get { return _lastPostTitle; } 
     set { _lastPostTitle = value; } 
    } 
} 
+2

İpucu: DateTime'ı kullanabilirsiniz? Nullable <> türlerinde olduğu gibi Nullable için shorthand olarak. Örneğin. int? Null , Guid nedir? Nullable nedir –

+0

Başka bir yinelenen: http://stackoverflow.com/q/858080/385844 – phoog

+1

Bu soruya alakasız kodu kaldırabilir misiniz? Sadece bu satırı tutabilirsiniz: 'Nullable lastPostDate = (okuyucu [3] == DBNull.Value? null: Convert.ToDateTime (okuyucu [3]))' ' – gdoron

cevap

23

Böyle yapmak isteyebilirsiniz deneyin:

DateTime? lastPostDate = (DateTime?)(reader.IsDbNull(3) ? null : reader[3]); 

Karşılaştığınız sorun üçlü operatör sol ve sağ taraf arasında kalıcı bir döküm istemesi. Ve null DateTime'a gönderilemez.

Yukarıdaki çalışmalara dikkat edin, çünkü üçlünün her iki tarafı da nesnenin. Nesne, DateTime'a açıkça dökülüyor mu? hangi çalışır: okuyucu [3] aslında bir tarih olduğu sürece.

25

ile Forum için benim sınıf nesnesi bu iki tip nullable DateTime

var lastPostDate = reader[3] == DBNull.Value ? 
             null : 
            (DateTime?) Convert.ToDateTime(reader[3]); 
  • Kullanımıait olduğundan emin olun olduğunu Nullable<DateTime> yerinebir zaman tasarrufu ...
  • Daha iyi girinti kullanın? Benim yaptığım gibi ifade.

    aşağıdaki ?: operatör devletler için şartname:

    The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,

    • If X and Y are the same type, then this is the type of the conditional expression.

    • Otherwise, if an implicit conversion exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.

    • Otherwise, if an implicit conversion exists from Y to X, but not from X to Y, then X is the type of the conditional expression.

    • Otherwise, no expression type can be determined, and a compile-time error occurs.

    derleyici nedir kontrol etmez


Eric Lippert bu mükemmel açıklamalar blog bulduk Bu iki türü "tutabilir" türü. Bu durumda

:

  • null ve DateTime aynı tip değildir.
  • null

yüzden derleme zamanı hatası ile bitirmek null bir örtük dönüştürme yoktur DateTime

  • DateTime bir örtük dönüştürme yoktur.

  • +1

    bunun için teşekkür ederiz. Bunu takdir ediyorum. – ONYX

    +0

    @ KDM çalıştı. Eric Lippert blog'undan açıklama ekledim. Umarım beğenirsiniz. – gdoron

    +0

    mükemmel açıklamalar! –

    8

    Boş olanı atar: (DateTime?)null veya (Nullable<DateTime>)null.

    Ayrıca diğer cevaplar belirttiği gibi default(DateTime?) veya

    Ve default(Nullable<DateTime>), ayrıca oldukça değişmez null daha DateTime değeri döküm uygulayabilirsiniz kullanabilirsiniz.

    DÜZENLEME (Prutswonder cevabı benim yorum uyarlanmıştır):

    noktası türünden bir örtük dönüştürme varsa koşullu operatör kendi atama hedefinin türünü dikkate almaz, bu yüzden sadece derlemek olacaktır ikinci işlenenin üçüncü işleneninin tipine veya üçüncü işleneninin türüne ikinci işleneninin tipine.

    Örneğin, bu derlenmeyecektir:

    bool b = GetSomeBooleanValue(); 
    object o = b ? "Forty-two" : 42; 
    

    object ikinci ya da üçüncü işlenen ya Döküm Ancak, sorununu giderir dize orada da nesne int bir kapalı dönüştürme ve nedeniyle nesneye:

    object o = b ? "Forty-two" : (object)42; 
    

    veya

    object o = b ? (object)"Forty-two" : 42; 
    
    +0

    Neden birisinin bunu reddettiğinden emin değilim, görebildiğim kadarıyla doğru bir cevap var mı? – hvd

    5

    Sen c Bir bu

    var lastPostDate = reader[3] == DBNull.Value ? 
               default(DateTime?): 
               Convert.ToDateTime(reader[3]); 
    
    İlgili konular