【笔记】【LINQ编程技术内幕】第三章 定义扩展方法和分布方法

1. 扩展方法及其使用规则

  • 使用扩展方法可以扩展密封类型,无需继承
  • 利用扩展方法可以避免出现失控的深度继承层次体系
  • 扩展方法是静态类中的静态方法
  • 扩展方法第一个参数的类型之前必须使用this修饰符;this指带将要被扩展的类型
  • 不支持扩展属性、事件和操作符
  • 相对于实例方法而言,扩展方法的可视性要差一些,而且限制也会多一些
  • 拓展方法是通过实例语法来调用的
  • 拓展方法的优先级比常规方法要低;因此,如果某个类有用一个同名方法的话,那么被调用的将会是实例方法
  • 扩展方法得到只能感知的支持
  • 泛型扩展方法是得到支持的,事实上,System.Linq命名空间中许多LINQ关键字就是通过这个而实现的
  • 扩展方法能在字面量上调用
  • 拓展方法可以用在密封类和内部类上,因为扩展方法自动支持装箱和拆箱
  • 拓展方法并不是真正的成员,因此只能在其中访问被扩展对象的公共成员
  • 拓展方法隐式使用ExtensionAttribute
class Program
{
	static void Main(string[] args)
	{
		var song = new { Artist = "Jussi Bjorling", Song = "Aida" };
		song.Dump();
	}
}

// 静态类
public static class Dumper
{
	// 静态方法
	public static void Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
			}
			catch
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
			}
		}
	}
}

2. 带返回值的扩展方法

class Program
{
	static void Main(string[] args)
	{
		var songs = new
		{
			Artist = "Green Day",
			Song = "Wake Me Up When September Ends"
		};

		Console.WriteLine(songs.Dump());
	}
}

public static class Dumper
{
	// 带返回值得扩展方法
	public static string Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		StringBuilder builder = new StringBuilder();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				builder.AppendFormat(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
			builder.AppendLine();
		}
		return builder.ToString();
	}
}

3. 带参数得扩展方法

static void Main(string[] args)
{
	var song = new
	{
		Artist = "Avril Lavigne",
		Song = "My Happy Ending"
	};

	song.Dump(Console.Out);
}



public static class Dumper
{
	public static void Dump(this Object o, TextWriter writer)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, p.GetValue(o, null)));
			}
			catch
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name, "unk."));
			}
		}
	}
}

4. 重载扩展方法

class Program
{
	static void Main(string[] args)
	{
		var songs = new[]
		{
		  new {Artist="Jussi Bjorling", Song="Aida"},
		  new {Artist="Sheryl Crow", Song="Steve McQueen"}
		};

		songs.Dump();
	}
}



public static class Dumper
{
	public static void Dump(this Object o)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				Debug.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
		}
	}

	public static void Dump(this IList list)
	{
		foreach (object o in list)
			o.Dump();
	}
}

5. 泛型扩展方法

class Program
{
	static void Main(string[] args)
	{
		// 连接字符串
		string connectionString = "Data Source=CASPAR;Initial Catalog=Northwind;Integrated Security=True";
		
		// 存储结果集合
		List<Order> orders = new List<Order>();

		// 数据库连接
		using (SqlConnection connection = new SqlConnection(connectionString))
		{
			// 执行查询
			SqlCommand command = new SqlCommand("SELECT * FROM ORDERS", connection);
			command.CommandType = CommandType.Text;
			connection.Open();
			SqlDataReader reader = command.ExecuteReader();

			// 读取查询结果
			while (reader.Read())
			{
				Order order = new Order();
				
				// 根据读取得结果初始化Order实例
				order.Read(reader);
				// 存储结果
				orders.Add(order);
			}
		}

		// 显示结果
		orders.Dump(Console.Out);
	}
}

/// <summary>Order类得扩展方法,用于读取指定得字段。EntityClass拓展方法根据值是否为空返回不同得值</summary>
public static class ReaderHelper
{
	public static void Read(this Order order, IDataReader reader)
	{
		order.OrderID = order.SafeRead(reader, "OrderID", -1);
		order.CustomerID = order.SafeRead(reader, "CustomerID", "");
	}

	public static T SafeRead<T>(this EntityClass entity,IDataReader reader, string fieldName, T defaultValue)
	{
		try
		{
			object o = reader[fieldName];
			if (o == null || o == System.DBNull.Value)
				return defaultValue;

			return (T)Convert.ChangeType(o, defaultValue.GetType());
		}
		catch
		{
			return defaultValue;
		}
	}
}

/// <summary>封装扩展方法得静态类,该类中得拓展方法用于显示信息</summary>
public static class Dumper
{
	public static void Dump(this Object o, TextWriter writer)
	{
		PropertyInfo[] properties = o.GetType().GetProperties();
		foreach (PropertyInfo p in properties)
		{
			try
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,p.GetValue(o, null)));
			}
			catch
			{
				writer.WriteLine(string.Format("Name: {0}, Value: {1}", p.Name,"unk."));
			}
		}
	}

	public static void Dump<T>(this IList<T> list, TextWriter writer)
	{
		foreach (object o in list)
			o.Dump(writer);
	}
}


/// <summary>空得实体类,用于演示泛型拓展方法</summary>
public class EntityClass { }

/// <summary>该类继承自实体类</summary>
public class Order : EntityClass
{
	public Order(){}
	public int OrderID {get;set;}
	public string CustomerID {get;set;}
}

6. 拓展方法是如何支持LINQ得

LIQN是一种语法糖,在底层调用的则是对应的拓展方法。

LIQN查询

var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };

var evens = from num in numbers where num % 2 == 0 select num;

foreach (var result in evens)
	Console.WriteLine(result);

拓展方法

var numbers = new int[] { 1966, 1967, 1968, 1969, 1970 };

var evens = numbers.Where(item => item % 2 == 0).Select(item=>item);

foreach (var result in evens)
	Console.WriteLine(result);

7. 分部方法

  • 分部方法要声明在分部类中
  • 分部方法要使用partial修饰符
  • 分部方法在声明时不能有方法体
  • 分部方法之呢个返回void
  • 分部方法可以时静态的,而且可以有参数和参数修饰符
  • 分部方法是私有的,不过不能再字面上使用访问修饰符;也就是说,你不能显示使用private关键字
  • 编译器忽略未使用的分部方法
class Program
{
	static void Main(string[] args)
	{
		// 复合类型初始化
		CustomerList customers = new CustomerList
			{
				new Customer{CustomerID=1, Name="Levi, Ray and Shoup"},
				new Customer{CustomerID=2, Name="General Dynamics Land Systems"},
				new Customer{CustomerID=3, Name="Microsoft"}
			};

		customers.Dump();
	}
}

// 分部类
public partial class CustomerList
{
	private string propertyName;
	private SortDirection direction;

	// 分部方法
	partial void SpecialSort(string propertyName, SortDirection direction)
	{
		this.propertyName = propertyName;
		this.direction = direction;

		Sort(Comparer);
	}

	/// <summary>
	/// Using an integer to change the direction of the sort was a suggestion made by 
	/// Chris Chartran, my good friend from Canada
	/// </summary>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <returns></returns>
	private int Comparer(Customer x, Customer y)
	{
		try
		{
			PropertyInfo lhs = x.GetType().GetProperty(propertyName);
			PropertyInfo rhs = y.GetType().GetProperty(propertyName);

			int directionChanger = direction == SortDirection.Ascending ? 1 : -1;

			object o1 = lhs.GetValue(x, null);
			object o2 = rhs.GetValue(y, null);

			if (o1 is IComparable && o2 is IComparable)
			{
				return ((IComparable)o1).CompareTo(o2) * directionChanger;
			}

			// no sort
			return 0;
		}
		catch (Exception ex)
		{
			Debug.WriteLine(ex.Message);
			return 0;
		}
	}
}

// 分部类
public partial class CustomerList : List<Customer>
{
	// 声明分部方法
	partial void SpecialSort(string propertyName, SortDirection direction);

	public void Dump()
	{
		SpecialSort("CustomerID", SortDirection.Descending);

		foreach (var customer in this)
			Console.WriteLine(customer.ToString());
	}
}


public class Customer
{
	public int CustomerID { get; set; }
	public string Name { get; set; }

	public override string ToString()
	{
		return string.Format("CustomerID={0}, Name={1}", CustomerID, Name);
	}
}

 

训练数据保存为deep_convnet_params.pkl,UI使用wxPython编写。卷积神经网络(CNN)是一种专门针对图像、视频等结构化数据设计的深度学习模型,在计算机视觉、语音识别、自然语言处理等多个领域有广泛应用。其核心设计理念源于对生物视觉系统的模拟,主要特点包括局部感知、权重共享、多层级抽象以及空间不变性。 **1. 局部感知与卷积操作** 卷积层是CNN的基本构建块,使用一组可学习的滤波器对输入图像进行扫描。每个滤波器在图像上滑动,以局部区域内的像素值与滤波器权重进行逐元素乘法后求,生成输出值。这一过程能够捕获图像中的边缘、纹理等局部特征。 **2. 权重共享** 同一滤波器在整个输入图像上保持相同的权重。这显著减少了模型参数数量,增强了泛化能力,并体现了对图像平移不变性的内在假设。 **3. 池化操作** 池化层通常紧随卷积层之后,用于降低数据维度并引入空间不变性。常见方法有最大池化平均池化,它们可以减少模型对微小位置变化的敏感度,同时保留重要特征。 **4. 多层级抽象** CNN通常包含多个卷积池化层堆叠在一起。随着网络深度增加,每一层逐渐提取更复杂、更抽象的特征,从底层识别边缘、角点,到高层识别整个对象或场景,使得CNN能够从原始像素数据中自动学习到丰富的表示。 **5. 激活函数与正则化** CNN中使用非线性激活函数来引入非线性表达能力。为防止过拟合,常采用正则化技术,如L2正则化Dropout,以增强模型的泛化性能。 **6. 应用场景** CNN在诸多领域展现出强大应用价值,包括图像分类、目标检测、语义分割、人脸识别、图像生成、医学影像分析以及自然语言处理等任务。 **7. 发展与演变** CNN的概念起源于20世纪80年代,其影响力在硬件加速大规模数据集出现后真正显现。经典模型如LeNet-5用于手写数字识别,而AlexNet、VGG、GoogLeNet、ResNet等现代架构推动了CNN技术的快速发展。如今,CNN已成为深度学习图像处理领域的基石,并持续创新。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
内容概要:本文介绍了一种基于CEEMDAN-BiLSTM的中短期天气预测模型,通过将完全集合经验模态分解自适应噪声(CEEMDAN)与双向长短期记忆网络(BiLSTM)相结合,实现对复杂气象时间序列的高精度预测。首先利用CEEMDAN对原始气象数据进行多尺度分解,获得多个本征模态函数(IMF)分量残差,有效解决模式混叠与噪声干扰问题;随后对各IMF分量分别构建BiLSTM模型进行独立预测,充分发挥其对前后时序依赖的建模能力;最后通过集成重构输出最终预测结果。文中还包含了数据预处理、特征提取、模型评估与可视化等完整流程,并提供了MATLAB实现的部分代码示例。该方法显著提升了天气预测的准确性与鲁棒性,适用于多类气象要素的中短期趋势预测。; 适合人群:具备一定机器学习时间序列分析基础,从事气象、环境、能源等领域研究或工程应用的研发人员、高校研究生及数据科学家。; 使用场景及目标:①应用于温度、风速、降水等气象变量的中短期精准预测;②解决传统模型在非线性、多尺度气象信号建模中的局限性;③构建智能气象预测系统,服务于电力调度、灾害预警、智慧农业等实际业务场景。; 阅读建议:建议结合MATLAB代码实践操作,深入理解CEEMDAN分解机制与BiLSTM建模细节,重点关注数据预处理、模型参数调优与结果集成策略,同时可扩展至多变量联合预测以提升应用价值。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhy29563

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值