平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“C# 利用委托给类内部传参的详细过程”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
假设有一个类定义如下所示
public class CheckBoxInfo:ReactiveObject
{
public CheckBoxInfo(ObservableCollection<CheckBoxInfo> parentCollection)
{
_parentCollection = parentCollection;
}
private readonly ObservableCollection<CheckBoxInfo> _parentCollection;
private string _text;
public string Text
{
get => _text;
set => this.RaiseAndSetIfChanged(ref _text, value);
}
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
this.RaiseAndSetIfChanged(ref _isSelected, value);
}
}
}
结合项目来看,想在IsSelected 属性的set方法中做一些操作,这些操作需用到一个bool类型的参数:
就像这样子:
public bool IsSelected
{
get => _isSelected;
set
{
// 只在选中时处理单选逻辑
if (value && _parentCollection != null)
{
if (true)
{
// 单选模式:取消其他所有选中项
}
else
{
// 多选模式:不做任何额外处理
}
}
this.RaiseAndSetIfChanged(ref _isSelected, value);
}
}
结合项目来看,因为要在set方法里采用这个bool类型参数,最容易想到的就是在这个类里面定义一个字段来保存这个变量,但是定义字段的话,又会破坏类的封装,这个时候能够借助委托传递这个参数,做法就是在类里面定义一个得到bool的委托:
private readonly Func<CheckBoxSelectionMode> _getSelectionMode;
然后在构造函数中对齐赋值
public CheckBoxInfo(Func<CheckBoxSelectionMode> getSelectionMode)
{
_getSelectionMode = getSelectionMode;
}
调用:
var checkBoxes = new ObservableCollection<CheckBoxInfo>();
foreach (var choice in choiceStrings)
{
checkBoxes.Add(new CheckBoxInfo(checkBoxes, () => currentSelectionMode)
{
Text = choice,
IsSelected = false,
});
}
用到的地方直接Invoke:
public bool IsSelected
{
get => _isSelected;
set
{
// 只在选中时处理单选逻辑
if (value && _parentCollection != null)
{
var currentMode = _getSelectionMode?.Invoke() ?? CheckBoxSelectionMode.Multiple;
if (currentMode == CheckBoxSelectionMode.Single)
{
// 单选模式:取消其他所有选中项
foreach (var item in _parentCollection)
{
if (item != this && item.IsSelected)
{
item.IsSelected = false;
}
}
}
// 多选模式:不做任何额外处理
}
this.RaiseAndSetIfChanged(ref _isSelected, value);
}
}
目前我感觉这样比直接定义字段更优雅一点
理解这一步时,总的来说,C# 委托传参适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。