C# 只有在Blazor状态管理中第一次调用时反射才成功
我发现了一个奇怪的行为,我完全不知道它来自哪里,也不知道如何修复它。 blazor状态管理(基于中介模式)出现问题-可以在以下位置找到库: 假设枚举有以下基类:C# 只有在Blazor状态管理中第一次调用时反射才成功,c#,.net-core,state,blazor,blazor-webassembly,C#,.net Core,State,Blazor,Blazor Webassembly,我发现了一个奇怪的行为,我完全不知道它来自哪里,也不知道如何修复它。 blazor状态管理(基于中介模式)出现问题-可以在以下位置找到库: 假设枚举有以下基类: 公共抽象类Simple,其中TSimple:Simple { 私有只读字符串\u密钥; 受保护的简单(字符串键) { _钥匙=钥匙; } 公共虚拟字符串键=>\u键; 公共静态t简单创建(字符串键) { var obj=All.SingleOrDefault(e=>e.Key==Key); 返回obj; } 公共静态IReadOnlyC
公共抽象类Simple,其中TSimple:Simple
{
私有只读字符串\u密钥;
受保护的简单(字符串键)
{
_钥匙=钥匙;
}
公共虚拟字符串键=>\u键;
公共静态t简单创建(字符串键)
{
var obj=All.SingleOrDefault(e=>e.Key==Key);
返回obj;
}
公共静态IReadOnlyCollection All=>GetAll();
私有静态IReadOnlyCollection GetAll()
{
var enumerationType=typeof(TSimple);
返回enumerationType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlatterHierarchy)
.Where(info=>enumerationType.IsAssignableFrom(info.FieldType))
.Select(info=>info.GetValue(null))
.Cast()
.ToArray();
}
}
以及以下枚举实现:
public class SimpleImpl : Simple<SimpleImpl>
{
public static readonly SimpleImpl One = new SimpleImpl("Important");
public static readonly SimpleImpl Two = new SimpleImpl("Urgent");
public static readonly SimpleImpl Three = new SimpleImpl("ImportantAndUrgent");
public static readonly SimpleImpl Four = new SimpleImpl("None");
private SimpleImpl(string key) : base(key)
{
}
}
这个样本的作用是:
public partial class AppState
{
public class AddAction : IAction
{
public AddAction(string simple)
{
Simple = simple;
}
public string Simple { get; }
}
}
此代码在.NETCore3.1下运行。
如果有人能告诉我问题所在,我将非常感谢。感谢你帮助我找到了问题所在。
基本上,这一切都归结为中介。发送和状态处理
在Blazor状态库中,当一个人分派和处理一个操作时,就会创建一个克隆(因此作为开发人员,您不必处理这个操作)。但正是由于Simple
(基本上是一个枚举类)的静态特性,这种克隆在这里搞砸了
为了解决这个问题,州政府可以实施ICloneable,并自行完成这项工作
一个非常天真的方法是:
public partial class AppState : State<AppState>, ICloneable
{
private List<SimpleImpl> _simples = new List<SimpleImpl>();
public IReadOnlyList<SimpleImpl> Simples => _simples.AsReadOnly();
public override void Initialize()
{
_simples = new List<SimpleImpl>();
}
public object Clone()
{
var state = new AppState { _simples = _simples};
return state;
}
}
公共部分类AppState:状态,可克隆
{
私有列表_simples=新列表();
公共IReadOnlyList Simples=>_Simples.AsReadOnly();
公共覆盖无效初始化()
{
_simples=新列表();
}
公共对象克隆()
{
var state=newappstate{{u simples=\u simples};
返回状态;
}
}
您可以添加blazor webassembly或blazor服务器端标记吗?添加了webassembly(客户端blazor)它应该可以工作。试着做一个,没有目标和grpc等。我将你的简单代码粘贴到一个新的废弃项目中,但无法复制。Ping@steventcramerI将调整我的示例并删除grpc部分,因为它不相关
public partial class AppState : State<AppState>
{
public IList<SimpleImpl> Simples { get; private set; }
public override void Initialize()
{
Simples = new List<SimpleImpl>();
}
}
public partial class AppState
{
public class AddAction : IAction
{
public AddAction(string simple)
{
Simple = simple;
}
public string Simple { get; }
}
}
public partial class AppState : State<AppState>, ICloneable
{
private List<SimpleImpl> _simples = new List<SimpleImpl>();
public IReadOnlyList<SimpleImpl> Simples => _simples.AsReadOnly();
public override void Initialize()
{
_simples = new List<SimpleImpl>();
}
public object Clone()
{
var state = new AppState { _simples = _simples};
return state;
}
}