随笔-145  评论-311  文章-50  trackbacks-17

.net 2.0中一个小小的疑惑

前几天工作中遇到一种这样的需求。
public class A
{
    private DateTime? _serverDateTime;
    public DateTime ServerDateTime
    {
         get {
             if(_serverDateTime.HasValue)
            {
               return _serverDateTime.Value;  }
           throw new CustomException("");
        }
        set
       {
              _serverDateTime = value;
        }
    }
}
在编译以下代码
A a = new A();
a.ServerDateTime = null;
时报错,提示ServerDateTime是DateTime类型不允许赋予Null值。
晕!!!!
其实我是给_serverDateTime赋值,也是DateTime?类型,应该可以接受为Null的值。可编译器确还是去校验非空属类型的类型,不能不说是一个遗憾。结果呢
把DateTime?的修饰符改为public,实属无奈之举。
看来ms还没有把空属类型处理好。
posted on 2006-08-26 12:45 蝈蝈 阅读(741) 评论(12) 编辑 收藏

评论:
#1楼 2006-08-26 13:17 | in my sleeper[未注册用户]
。。。晕倒,搂主你逻辑上有错误啊。。。
public DateTime ServerDateTime
改为
public DateTime? ServerDateTime
微软不会这么弱智

 回复 引用   
#2楼 2006-08-26 13:20 | jijl2001[未注册用户]
应该为public DateTime? ServerDateTime
不知道为什么你那样也能编译通过?

 回复 引用   
#3楼 2006-08-26 14:44 | idior      
public void SetServerDateTime(DataTime dateTime)
{
_serverDateTime=dateTime;
}

你认为SetServerDateTime(null);会产生什么结果?

 回复 引用 查看   
#4楼 2006-08-26 15:32 | 达达      
搂主,如果你的属性要对应int?或者DateTime?这种类型要类似:

public Nullable<DateTime> JoinTime
{
get { return _jointime; }
set { _jointime = value; }
}

 回复 引用 查看   
#5楼 2006-08-26 15:54 | 沛沛      
请问搂主:

private DateTime? _serverDateTime;
中的那个问号表示啥子意思啊?

 回复 引用 查看   
#6楼[楼主] 2006-08-26 18:08 | 蝈蝈      
?号表示空属类型,也就是可以接受null值。与Nullable<T>一样的效果。

可能是我没有说清楚,我再描述一下
假如是这样
private DateTime? _serverDateTime;
public DateTime? ServerDateTime { get{...} set {...}}
那客户调用时就需要判断ServerDateTime是否有值,且要调用Value属性,这样与普通的属性调用不一样。复杂了一些,为了兼容以前的写法,屏蔽细节,所以我选用DateTime类型,但希望能接收一个Null值。因为Null值在这里有特殊的意义,或许有人会说Null值的特殊可以用DateTime.MinValue或max来代替,确实,但有了空属类型为什么不用呢,难道还要用这种过时的处理方式么。

不知道有没有说清楚,我也确实没有想到更好的解决办法,希望大家指点。


 回复 引用 查看   
#7楼[楼主] 2006-08-26 18:26 | 蝈蝈      
不过,细细想来还能发现更多的问题,或许可以深入到framework的设计了,虽然对这方面从没有研究,但深入下面确实会感到知识的无穷无尽。

假如在C#中没有属性,那么我们会希望这样来写,当然前提我们还是希望隐藏细节,也就是把字段设置为private。
private DateTime? _serverDateTime;
public DateTime GetServerDateTime(){
if(_serverDateTime.HasValue){
return _serverDateTime.Value;
}
throw new MyException();
}
public void SetServerDateTime(DateTime? value){
_serverDateTime = value;
}
这样显示没有任何问题,且如果我们把方法名字前面的Get和Set除去,也能够成重载。那么为什么属性就不行呢?这是一个值得思考的问题,或许再深入下去,去查看IL,属性的处理应该是拆分成以上类似的两个方法,这一点我不敢确定,有兴趣的朋友可以去研究一下。
既然有了属性,也就是说ms希望把代码简化,对属性的访问提供get和set关键字,丢弃了对一个属性写两个方法和二个属性(一个get和一个set)那么,没有道理不支持我前面提到的代码实现。

注:抛出自定义的异常是想通过统一的处理方法来解决同一类问题。也就是当得到ServerDateTime属性值为Null时应该提示客户服务器应该程序暂时不可用。

 回复 引用 查看   
#8楼 2006-08-26 22:16 | p2p[未注册用户]
.Net IL里对的处理就是两个方法,这个应该是.NET的入门常识

public DateTime ServerDateTime
{
get {
if(_serverDateTime.HasValue)
{
return _serverDateTime.Value; }
throw new CustomException("");
}
set
{
_serverDateTime = value;
}
}
编译后成为:
public DateTime GetServerDateTime(){
if(_serverDateTime.HasValue){
return _serverDateTime.Value;
}
throw new MyException();
}




public void SetServerDateTime(DateTime value){
_serverDateTime = value;
}


 回复 引用   
#9楼 2006-08-27 06:57 | King_Boy_Hcc      
我不懂那么深,,呵呵,但看样子这个问题可以拿到"原创首页"去讨论讨论,肯定让人看的不想睡觉
 回复 引用 查看   
#10楼[楼主] 2006-08-27 10:29 | 蝈蝈      
按p2p说法,那么ms为什么还把
public void SetServerDateTime(DateTime value){
_serverDateTime = value;
}这个方法的入参类型认为是DateTime而不是_serverDateTime类型DateTime?呢

既然最终的值是保存在_serverDateTime中,那么没有理由不接受null值。
看来确实是一个小小的遗憾,但愿在3.0中会解决。

 回复 引用 查看   
#11楼[楼主] 2006-08-27 10:45 | 蝈蝈      
不明白dudu为什么把这类文章移到.net新手区中,对于.net新手区和首页精华本人没有完全理解,或许很多人都像我一样。如果是那样,是不是博客园的分类存在问题呢?暂且不说分类的问题,仅从习惯和使用上来说,大部分人都只会关注首页,其它类别的人气太低,这样不得不促使委有多人把自己的文章放到首页,特别是针对问题的讨论贴。
不知道dudu每天要调整多少贴的版块,如果超过10个可想而知是分类存在问题了,或者是表达不清楚,当然也有上面说的其它原因。
以上言辞不是针对dudu本人,而是希望博客园越来越好。

 回复 引用 查看   
#12楼 2007-01-08 17:33 | 快乐永远(syeerzy)[未注册用户]
不妨看看这几个情况:
一:
private int _count;
public string Count
{
set
{
_count = int.Parse(value); //简要说明,所以省略错误处理和 get
}
}
你觉得按你的逻辑,微软应该实现成什么样呢?
SetCount(int) 还是 SetCount(string) ?

二:
假设按你觉得的,应该用原始字段的类型,但是,编译器如何得知原始字段是哪个字段呢? 我们可以看出来,因为命名规范,但是编译器显然不能从命名规范去看出来,编译器不得不考虑一些"差"的代码,比如,有人在一个属性的Set方法里放了一千行代码,并且引用了许多个字段,比如属性是一个DateTime,然后字段是年月日3个int字段, 那又怎么办? 字段和属性不必要是1对1的.


三:
你也说了隐藏实现,那么压根就不该让调用者知道字段是什么类型,调用者只要知道属性的类型就够了. 所以,要求调用者用原始的字段类型来给属性赋值显然是不现实的. DateTime 和DateTime? 是两种类型,就像 int 和String一样.
显然上面我举的例子,不能期望:

private int _count;
public string Count
{
set
{
_count = value; //简要说明,所以省略错误处理和 get
}
}

而让调用者使用
AAA.Count = 1;
因为调用者100%会写
AAA.Count = "1";
因为他们不知道里面的细节,所以只能写"1",谁知道下面是int呢?


 回复 引用   
基本资料:
蝈蝈
QQ:*******
MSN:hotsoho#msn.com
2004年09月30日
Dial Up
昵称:蝈蝈
园龄:7年4个月
粉丝:1
关注:0
<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

搜索

 
 

常用链接

随笔分类

随笔档案

文章分类

文章档案

相册

精品收藏

友情链接

积分与排名

  • 积分 - 124444
  • 排名 - 804

最新评论

阅读排行榜

评论排行榜

推荐排行榜