C# 在HttpRuntime缓存中缓存IEnumerable和IList有区别吗?
假设以下代码段缓存两个对象集合C# 在HttpRuntime缓存中缓存IEnumerable和IList有区别吗?,c#,list,caching,ienumerable,httpruntime.cache,C#,List,Caching,Ienumerable,Httpruntime.cache,假设以下代码段缓存两个对象集合MyObject:一个集合类型为IEnumerable,另一个类型为List。代码从缓存中检索值,然后访问集合: class Program { static void Main(string[] args) { CacheManager.CacheSomething(); } public class MyService { private IEnumerable<AnObject&g
MyObject
:一个集合类型为IEnumerable
,另一个类型为List
。代码从缓存中检索值,然后访问集合:
class Program
{
static void Main(string[] args)
{
CacheManager.CacheSomething();
}
public class MyService
{
private IEnumerable<AnObject> AnObjects
{
get
{
return new[]
{
new AnObject {MyString1 = "one", MyString2 = "two"},
new AnObject {MyString1 = "three", MyString2 = "four"}
};
}
}
public IEnumerable<AnObject> GetEnumerable()
{
return AnObjects;
}
public List<AnObject> GetList()
{
// Run it out to a list
return AnObjects.ToList();
}
}
public static class CacheManager
{
public static void CacheSomething()
{
// Get service
var service = new MyService();
// Get the values as List and Enumerable
var list = service.GetList();
var enumerable = service.GetEnumerable();
// Putting them in a cache
HttpRuntime.Cache.Insert("list", list);
HttpRuntime.Cache.Insert("enumerable", enumerable);
// Get the values
var retrievedList = HttpRuntime.Cache["list"] as List<AnObject>;
var retrievedEnumerable = HttpRuntime.Cache["enumerable"] as IEnumerable<AnObject>;
// Access both
var res1 = retrievedList.ToList();
var res2 = retrievedEnumerable.ToList();
}
}
public class AnObject
{
public string MyString1 { get; set; }
public string MyString2 { get; set; }
}
}
类程序
{
静态void Main(字符串[]参数)
{
CacheManager.CacheSomething();
}
公共类MyService
{
私有IEnumerable对象
{
得到
{
返回新的[]
{
新对象{MyString1=“one”,MyString2=“two”},
新对象{MyString1=“三”,MyString2=“四”}
};
}
}
公共IEnumerable GetEnumerable()
{
返回一个对象;
}
公共列表GetList()
{
//把它列出来
返回AnObjects.ToList();
}
}
公共静态类缓存管理器
{
公共静态void CacheSomething()
{
//得到服务
var service=newmyservice();
//获取列表和可枚举的值
var list=service.GetList();
var enumerable=service.GetEnumerable();
//把它们放在缓存里
Insert(“list”,list);
Insert(“可枚举的”,可枚举的);
//获取值
var retrievedList=HttpRuntime.Cache[“list”]作为列表;
var retrievedEnumerable=HttpRuntime.Cache[“enumerable”]作为IEnumerable;
//访问两者
var res1=retrievedList.ToList();
var res2=retrievedEnumerable.ToList();
}
}
公共类对象
{
公共字符串MyString1{get;set;}
公共字符串MyString2{get;set;}
}
}
根据集合类型,存储这些对象所需的内存量是否存在差异
我问这个问题的原因是,当我们分析应用程序时,我们注意到当我们查看依赖关系树时,IEnumerable
有与之关联的服务。这是否意味着它也缓存服务
有人能解释一下这是否是一个值得关注的问题吗?在缓存中存储
IEnumerable
是否有问题?我们是否更喜欢缓存List
s而不是IEnumerable
s?内存量的差异?没有
为什么?IEnumerable
不是一种类型;这是一个界面。这意味着IEnumerable
中存储的任何内容实际上都是实现IEnumerable
的其他类型(例如List
)
IEnumerable
仅强制实现读取列表的方法。它不适合修改集合。这就是为什么要将其强制转换为实际类型(如List
),以便可以使用Add
等方法来增加内存量?没有
为什么?IEnumerable
不是一种类型;这是一个界面。这意味着IEnumerable
中存储的任何内容实际上都是实现IEnumerable
的其他类型(例如List
)
IEnumerable
仅强制实现读取列表的方法。它不适合修改集合。这就是为什么您希望将其强制转换为实际类型(如List
),以便可以使用Add
和IEnumerable
为非数据等方法。这是一个承诺,你会收到数据时,你问。有些数据可能实现它(数组、列表),但有时它不是物化数据,而是对数据库的查询
“缓存”您的IEnumerable
意味着您将知识缓存在哪里获取数据。那不是你想要的。您希望缓存数据本身
在缓存结果(例如使用ToList或ToArray)之前,始终具体化您的IEnumerable
s。否则,您可能会得到一个缓存,该缓存只保存一个被调用以获取数据的过程
在您的示例中,
IEnumerable
仍然保存对服务的引用,这一事实正是:它不保存数据,它保存对服务的引用,并在您使用它时再次调用它。因此,与您希望从缓存中得到的正好相反。和IEnumerable
是而不是数据。这是一个承诺,你会收到数据时,你问。有些数据可能实现它(数组、列表),但有时它不是物化数据,而是对数据库的查询
“缓存”您的IEnumerable
意味着您将知识缓存在哪里获取数据。那不是你想要的。您希望缓存数据本身
在缓存结果(例如使用ToList或ToArray)之前,始终具体化您的IEnumerable
s。否则,您可能会得到一个缓存,该缓存只保存一个被调用以获取数据的过程
在您的示例中,
IEnumerable
仍然保存对服务的引用,这一事实正是:它不保存数据,它保存对服务的引用,并在您使用它时再次调用它。因此,这与您希望从缓存中得到的正好相反。如果您已经完成了所有这些内容的编写过程,为什么不更进一步,使用基准工具来查看两者的性能以及它们的分配情况?我刚刚花了一天中最长的时间来研究这一点,但仍然没有具体的答案。要证明这一点可能比你想象的要难。如果你已经完成了写这些东西的过程,为什么不更进一步,使用一个基准工具来看看两者的表现和分配情况呢?