在C#中如何获取list表中不同物体所对应的不同类型
时间: 2024-02-22 16:57:43 浏览: 83
在 C# 中,如果要获取 List 中不同物体所对应的不同类型,可以使用 LINQ 查询语句来实现。具体步骤如下:
1. 导入 System.Linq 命名空间。
2. 使用 LINQ 查询语句对 List 进行筛选,然后使用 Select() 方法提取 List 中每个元素的类型,最后使用 Distinct() 方法去重,得到不同的类型集合。
以下是示例代码:
```csharp
using System.Collections.Generic;
using System.Linq;
List<object> myList = new List<object>();
myList.Add(1);
myList.Add("string");
myList.Add(3.14);
var distinctTypes = myList.Select(x => x.GetType()).Distinct();
foreach (var type in distinctTypes)
{
Console.WriteLine(type);
}
```
输出结果为:
```
System.Int32
System.String
System.Double
```
这样就能获取 List 中不同物体所对应的不同类型了。
相关问题
unity 一级二级菜单控制脚本,一级菜单按钮为toggle 有多个,控制对应二级菜单父物体显隐,二级菜单父物体下为二级菜单分类父物体,二级菜单分类父物体之下为二级菜单按钮,按钮分toggle和button两类,分别绑定不同方法,关闭二级菜单时对二级菜单按钮做初始化,编写控制脚本并挂载到unity场景,使用MVC框架
首先,我们需要定义菜单的数据模型和视图模型。
```c#
// 菜单项的数据模型
public class MenuItemModel
{
public string name; // 菜单项名称
public List<MenuItemModel> subItems; // 子菜单项
public bool isToggle; // 是否是 toggle 类型的按钮
}
// 菜单的视图模型
public class MenuViewModel
{
public List<MenuItemModel> items; // 菜单项列表
public int selectedToggleIndex = -1; // 当前选中的 toggle 按钮的索引
public bool isMenuOpen = false; // 是否打开菜单
}
```
接下来,我们可以编写控制脚本了。
```c#
public class MenuController : MonoBehaviour
{
private MenuViewModel viewModel;
private void Start()
{
// 初始化视图模型
viewModel = new MenuViewModel();
viewModel.items = new List<MenuItemModel>();
// 添加菜单项
MenuItemModel item1 = new MenuItemModel();
item1.name = "一级菜单1";
item1.isToggle = true;
item1.subItems = new List<MenuItemModel>();
item1.subItems.Add(new MenuItemModel() { name = "二级菜单1-1", isToggle = false });
item1.subItems.Add(new MenuItemModel() { name = "二级菜单1-2", isToggle = true });
item1.subItems.Add(new MenuItemModel() { name = "二级菜单1-3", isToggle = true });
viewModel.items.Add(item1);
MenuItemModel item2 = new MenuItemModel();
item2.name = "一级菜单2";
item2.isToggle = true;
item2.subItems = new List<MenuItemModel>();
item2.subItems.Add(new MenuItemModel() { name = "二级菜单2-1", isToggle = false });
item2.subItems.Add(new MenuItemModel() { name = "二级菜单2-2", isToggle = true });
viewModel.items.Add(item2);
// 绑定视图模型到 UI
BindViewModel();
}
private void BindViewModel()
{
// 绑定一级菜单项
for (int i = 0; i < viewModel.items.Count; i++)
{
int index = i; // 闭包,避免 lambda 表达式引用同一个变量
Toggle toggle = transform.Find($"Toggle{index + 1}").GetComponent<Toggle>();
toggle.isOn = false;
toggle.onValueChanged.AddListener((value) =>
{
OnToggleValueChanged(index, value);
});
}
// 绑定二级菜单项
for (int i = 0; i < viewModel.items.Count; i++)
{
Transform parent = transform.Find($"Submenu{ i + 1 }");
for (int j = 0; j < viewModel.items[i].subItems.Count; j++)
{
int subIndex = j;
Transform child = parent.Find($"Submenu{ i + 1 }-Item{ j + 1 }");
if (viewModel.items[i].subItems[j].isToggle)
{
Toggle toggle = child.GetComponent<Toggle>();
toggle.isOn = false;
toggle.onValueChanged.AddListener((value) =>
{
OnSubToggleValueChanged(i, subIndex, value);
});
}
else
{
Button button = child.GetComponent<Button>();
button.onClick.AddListener(() =>
{
OnSubButtonClick(i, subIndex);
});
}
}
}
// 绑定关闭菜单按钮
Button closeButton = transform.Find("CloseButton").GetComponent<Button>();
closeButton.onClick.AddListener(() =>
{
OnCloseButtonClick();
});
}
private void OnToggleValueChanged(int index, bool value)
{
if (value)
{
// 关闭其他的 toggle
for (int i = 0; i < viewModel.items.Count; i++)
{
if (i != index)
{
Toggle toggle = transform.Find($"Toggle{ i + 1 }").GetComponent<Toggle>();
toggle.isOn = false;
}
}
// 更新选中的 toggle 索引
viewModel.selectedToggleIndex = index;
// 显示对应的二级菜单
ShowSubmenu(index);
}
else
{
// 隐藏当前的二级菜单
HideSubmenu(index);
}
}
private void OnSubToggleValueChanged(int index, int subIndex, bool value)
{
// do something
}
private void OnSubButtonClick(int index, int subIndex)
{
// do something
}
private void OnCloseButtonClick()
{
// 关闭菜单
viewModel.isMenuOpen = false;
// 隐藏所有的二级菜单
for (int i = 0; i < viewModel.items.Count; i++)
{
HideSubmenu(i);
}
}
private void ShowSubmenu(int index)
{
Transform submenu = transform.Find($"Submenu{ index + 1 }");
submenu.gameObject.SetActive(true);
}
private void HideSubmenu(int index)
{
Transform submenu = transform.Find($"Submenu{ index + 1 }");
submenu.gameObject.SetActive(false);
}
}
```
最后,我们需要在 UI 中添加对应的组件。以一级菜单为例,我们可以在 Canvas 中添加多个 Toggle 组件,并将它们的 GameObject 名称分别设置为 "Toggle1"、"Toggle2" 等。在每个 Toggle 的子对象中添加一个 Text 组件,用于显示菜单项的名称。接着,我们需要添加二级菜单的父物体,并将它们的 GameObject 名称分别设置为 "Submenu1"、"Submenu2" 等。在每个二级菜单的父物体下添加多个 Toggle 或 Button 组件,用于显示二级菜单项的名称。在关闭菜单的按钮下添加一个 Button 组件,并将它的 GameObject 名称设置为 "CloseButton"。
C# OPENCV 轮廓
C# OpenCV 中的“轮廓”是指图像处理中检测到的目标边界线的集合。当我们对一张图片应用边缘检测算法(例如Canny边缘检测),我们实际上是在寻找那些区分图像背景和前景区域之间的边界点。这些边界点集合即形成一组轮廓。
在计算机视觉任务中,轮廓非常有用,比如物体识别、形状分析等。通过分析这些轮廓,我们可以提取出目标的基本几何特征,如面积、周长、中心点等信息,这对于自动识别和跟踪物体非常关键。
在C# OpenCV库中,你可以使用`findContours()`函数从经过边缘检测后的图像中找到所有轮廓。这个过程会返回一个包含所有检测到的轮廓的向量。每个轮廓通常是一个整数数组,表示该轮廓上连续的点坐标。
以下是基本步骤如何在C# OpenCV中使用轮廓:
1. 加载并预处理图像:这包括调整图像大小、灰度化以及应用边缘检测算法。
2. 使用 `FindContours()` 函数获取轮廓列表:传入经过预处理的图像,并指定一些参数,如轮廓检索模式和轮廓近似方法。
3. 分析轮廓:你可以遍历轮廓列表,并对每个轮廓执行进一步的操作,如计算其面积、形状因子、圆拟合等。
4. 绘制轮廓:最后一步可以将找到的轮廓绘制回原始图像,以便可视化检查结果。
下面是一段简单的示例代码说明如何使用C# OpenCV查找并绘制图像中的轮廓:
```csharp
using System;
using OpenCvSharp;
class Program {
static void Main(string[] args) {
// 加载图像
Mat image = Cv2.ImRead("path_to_image.jpg", ImreadModes.Color);
// 将彩色图像转换为灰度图
Mat grayImage = new Mat();
Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY);
// 应用Canny边缘检测算法
Mat edges = new Mat();
Cv2.Canny(grayImage, edges, 50, 150);
// 查找图像中的轮廓
var contours = new List<Mat>();
Cv2.FindContours(edges, ref contours, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
// 绘制轮廓
foreach (var contour in contours) {
Cv2.DrawContours(image, new List<Mat>{contour}, Scalar.Red, Scalar.Red, LineTypes.Line_8);
}
// 显示最终图像
Cv2.ImShow("Detected contours", image);
Cv2.WaitKey(0);
}
}
```
请注意,实际路径应替换为您实际的图像文件位置,并且可能需要安装适当的OpenCV.NET组件和库才能运行上述代码。此外,上述代码只是一个基础示例,实际应用中可能还需要考虑更多的参数调整和错误处理机制。
阅读全文