小编Aur*_*eer的帖子

是否隐式调用.Net属性设置器?

我正在使用C#编写ASP.Net 2.0项目.我有一些数据存储在会话状态.为了便于使用,它包含在属性中,如下所示:

protected IList<Stuff> RelevantSessionData
{
    get
    {
        return (IList<Stuff>) Session["relevant_key"];
    }
    set
    {
        Session["relevant_key"] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

获取和设置值完全符合您的预期.如果我想清除该值,我只需将其设置为null,并且没有问题.但是,在另一个开发人员的页面中,他调用了集合的Clear()方法.我认为这将是一个错误,但它似乎工作,我不明白为什么.它的工作原理如下:

Debug.WriteLine(RelevantSessionData.Count);    //outputs, say, 3
RelevantSessionData.Clear();
Debug.WriteLine(RelevantSessionData.Count);    //outputs 0
Run Code Online (Sandbox Code Playgroud)

为什么这样做?我天真的期望是中间行从会话加载序列化值,反序列化为对象,调用Clear()该对象,然后让未命名对象超出范围.这将是一个错误,因为存储在Session中的值将保持不变.但显然,它足够聪明,可以调用属性setter并将新更改的集合序列化回会话.

这让我有点紧张,因为我们的遗留代码中有些地方属性设置器有副作用,我不希望那些被调用,如果不是这样的话.

在这种情况下,属性setter是否总是被调用?还有别的事吗?或者我是否完全误解了这里发生的事情?

[补充解释答案]
事实证明误解了.我知道存储在Session中的对象必须是可序列化的,并且基于此我对集合在内部的行为做了太多假设.我是在思索.

存储对象(my IList)只有一个实例.每次调用getter都会返回对同一实例的引用.所以上面引用的代码就像看起来一样,不需要特殊的魔法.

并回答标题问题:不,不会暗中调用setter.

.net c# asp.net session properties

10
推荐指数
1
解决办法
1022
查看次数

声明从接口方法返回的结构

我在C#(2.0)中编写一个必须返回简单对象集合的方法.通常我会做这样的事情:

class MyWidget
{
    struct LittleThing
    {
        int foo;
        DateTime bar;
    }

    public IList<LittleThing> LookupThings()
    {
        // etc.
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我必须在接口中声明此方法.调用者无法看到MyWidget,只有一个IWidget界面.上述设置在这种情况下不起作用,因为C#不允许在接口内定义类型.做这种声明的正确或最佳方式是什么?

我想到的直接的事情是简单地LittleThing在界面之外声明.出于几个原因,这看起来并不好.一:它只用于那个单一类中的那个单一方法,所以它似乎不LittleThing应该是一个独立的类型,只是自己浮动.二:如果为其他类编写类似的方法,它们将返回不同类型的数据(出于良好的设计原因),并且我不希望使用大量相似命名的结构来混淆名称空间彼此.

如果我们可以升级我们的.Net版本,我只会返回一个Tuple<>,但这还不是一段时间的选择.

[编辑添加:小对象确实需要包含两个以上的字段,因此KeyValuePair<K,V>不会完全删除它.]

[编辑进一步补充:IWidget仅由一个类实现,Widget.我认为只有一个类的接口很奇怪,但这样做是为了满足旧的编码策略,该策略要求契约始终与实现分开.所述政策现已消失,但我们没有资源重构整个应用程序并删除所有不必要的接口.]

什么是最佳做法?

.net c# c#-2.0

6
推荐指数
2
解决办法
3300
查看次数

使用泛型类型参数进行上传

是否有可能从基于T的泛型类"upcast"到基于比T更通用的泛型类?

例如,假设我有一个名为Derived继承自名为的类的类Base.我可以做这样的事情:

List<Derived> der = new List<Derived>();
List<Base> bas = (List<Base>) der;
Run Code Online (Sandbox Code Playgroud)

或者,使用接口,是否可以执行以下操作:

List<MyClonableType> specific = new List<MyClonableType>();
List<IClonable> general = (List<IClonable>)specific;
Run Code Online (Sandbox Code Playgroud)

正如这里所写,每个例子都失败了InvalidCastException.我们争论的问题是它是否实际上是不可能的,或者只是一个语法错误,如果我们知道如何可以修复.

c# generics casting

6
推荐指数
1
解决办法
1855
查看次数

标签 统计

c# ×3

.net ×2

asp.net ×1

c#-2.0 ×1

casting ×1

generics ×1

properties ×1

session ×1