在" 我如何仅公开IList的片段<>问题"中,其中一个答案包含以下代码段:
IEnumerable<object> FilteredList()
{
foreach(object item in FullList)
{
if(IsItemInPartialList(item))
yield return item;
}
}
Run Code Online (Sandbox Code Playgroud)
yield关键字有什么作用?我已经看到它在几个地方被引用,另外一个问题,但我还没弄清楚它实际上做了什么.我习惯于在一个线程产生另一个线程的意义上考虑收益率,但这似乎并不重要.
在这个页面中,我找到了一个新的JavaScript函数类型:
// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13
function* fibonacci() { // !!! this is the interesting line !!!
let [prev, curr] = [0, 1];
for (;;) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经知道了什么yield,let以及[?,?]=[?,?]做的,但不知道什么function*是注定的.它是什么?
我正在尝试将DataTable转换为IEnumerable.其中T是我创建的自定义类型.我知道我可以通过创建一个List来实现它,但我认为使用IEnumerable有一种更流畅的方法.这就是我现在拥有的.
private IEnumerable<TankReading> ConvertToTankReadings(DataTable dataTable)
{
var tankReadings = new List<TankReading>();
foreach (DataRow row in dataTable.Rows)
{
var tankReading = new TankReading
{
TankReadingsID = Convert.ToInt32(row["TRReadingsID"]),
TankID = Convert.ToInt32(row["TankID"]),
ReadingDateTime = Convert.ToDateTime(row["ReadingDateTime"]),
ReadingFeet = Convert.ToInt32(row["ReadingFeet"]),
ReadingInches = Convert.ToInt32(row["ReadingInches"]),
MaterialNumber = row["MaterialNumber"].ToString(),
EnteredBy = row["EnteredBy"].ToString(),
ReadingPounds = Convert.ToDecimal(row["ReadingPounds"]),
MaterialID = Convert.ToInt32(row["MaterialID"]),
Submitted = Convert.ToBoolean(row["Submitted"]),
};
tankReadings.Add(tankReading);
}
return tankReadings.AsEnumerable();
}
Run Code Online (Sandbox Code Playgroud)
关键部分是我创建一个List然后使用AsEnumerable()返回它.
当我认为我可以使用yield关键字时,我退后一步,看看它将如何影响我的项目.我总是最终返回一个集合而不是yeilding,因为我觉得保持yeilding方法状态的开销不会给我带来太大的影响.在几乎所有我返回集合的情况下,我觉得90%的时间,调用方法将迭代集合中的所有元素,或者将在整个集合中寻找一系列元素.
我确实理解它在linq中的用处,但我觉得只有linq团队正在编写这样复杂的可查询对象,这些对象的产生是有用的.
有没有人写过像linq这样的产品有用吗?
到目前为止,收益是我很难理解的.但现在我抓住了它.现在,在一个项目中,如果我返回List,Microsoft代码分析将发出警告.所以,通常我会做所有必要的逻辑部分并将列表作为IEnumerable返回.我想知道两者之间的区别.意味着我是否正在收益率或其他方式.
这是我展示的一个非常简单的例子,通常代码有点复杂.
private static IEnumerable<int> getIntFromList(List<int> inputList)
{
var outputlist = new List<int>();
foreach (var i in inputList)
{
if (i %2 ==0)
{
outputlist.Add(i);
}
}
return outputlist.AsEnumerable();
}
private static IEnumerable<int> getIntFromYeild(List<int> inputList)
{
foreach (var i in inputList)
{
if (i%2 == 0)
{
yield return i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我能看到的一个重要好处是线路更少.但还有其他好处吗?我应该更改和更新返回IEnumearble以使用yield而不是List的函数吗?什么是最好的方式或更好的做事方式?
在这里,我可以在List上使用简单的lambda表达式,但通常情况并非如此,这个例子专门用于理解编码的最佳方法.
这是我用来从数据库中获取数据的示例代码:在DAO层:
public IEnumerable<IDataRecord> GetDATA(ICommonSearchCriteriaDto commonSearchCriteriaDto)
{
using(DbContext)
{
DbDataReader reader = DbContext.GetReader("ABC_PACKAGE.GET_DATA", oracleParams.ToArray(), CommandType.StoredProcedure);
while (reader.Read())
{
yield return reader;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在BO层我调用上面的方法,如:
List<IGridDataDto> GridDataDtos = MapMultiple(_costDriversGraphDao.GetGraphData(commonSearchCriteriaDto)).ToList();
Run Code Online (Sandbox Code Playgroud)
在mapper层上MapMultiple方法的定义如下:
public IGridDataDto MapSingle(IDataRecord dataRecord)
{
return new GridDataDto
{
Code = Convert.ToString(dataRecord["Code"]),
Name = Convert.ToString(dataRecord["Name"]),
Type = Convert.ToString(dataRecord["Type"])
};
}
public IEnumerable<IGridDataDto> MapMultiple(IEnumerable<IDataRecord> dataRecords)
{
return dataRecords.Select(MapSingle);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码运行良好,但我想知道上述代码的两个问题.
我希望以一种易于理解的形式了解该声明的所有内容yield.
我已经阅读了关于yield实现迭代器模式时的语句及其简易性.但是,大部分都非常干燥.我想深入研究微软如何处理收益率.
另外,你什么时候使用收益率突破?
c# ×9
yield ×5
.net ×2
linq ×2
yield-return ×2
asp.net ×1
c#-4.0 ×1
datareader ×1
datatable ×1
ecmascript-6 ×1
function ×1
ienumerable ×1
iterator ×1
javascript ×1
syntax ×1
using ×1