egametang/ET · error · NotSupportedException
{runtimeType.FullName} 缺少可用于导出的公共构造函数。必须通过构造函数提供的成员: {names}
Error message
{runtimeType.FullName} 缺少可用于导出的公共构造函数。必须通过构造函数提供的成员: {names}。请补充例如 [BsonConstructor] public {runtimeType.Name}({parameters}) What it means
Thrown by ResolveConstructor when emitting a complex object: the emitter needs a public constructor whose parameters (by name, case-insensitively, and by exact type) bind ALL serializable constructor-members, and either no constructor matched, or more than one matched without a [BsonConstructor] tiebreaker. The message lists the required member names and a suggested signature to copy.
Source
Thrown at Packages/cn.etetet.config/Scripts/Model/Share/CSharpObjectCodeEmitter.cs:414
{
continue;
}
matches.Add(match);
}
ConstructorMatch attributeMatch = matches.SingleOrDefault(match => match.Constructor.GetCustomAttribute<BsonConstructorAttribute>() != null);
if (attributeMatch != null)
{
return attributeMatch;
}
if (matches.Count == 1)
{
return matches[0];
}
throw new NotSupportedException(this.BuildMissingConstructorMessage(runtimeType, ctorMembers));
}
private bool TryMatchConstructor(ConstructorInfo constructor, List<SerializableMember> ctorMembers, out ConstructorMatch match)
{
match = null;
ParameterInfo[] parameters = constructor.GetParameters();
Dictionary<string, SerializableMember> membersByKey = this.BuildConstructorMemberLookup(ctorMembers);
List<ConstructorArgument> arguments = new();
HashSet<SerializableMember> boundMembers = new();
foreach (ParameterInfo parameter in parameters)
{
if (!membersByKey.TryGetValue(parameter.Name ?? string.Empty, out SerializableMember member))
{
if (parameter.IsOptional)
{
continue;View on GitHub (pinned to 5cab01f7a8)
Solutions
- Add a public constructor whose parameters match the reported members by name (case-insensitive) and exact type, as suggested in the message.
- If multiple constructors qualify, annotate the canonical one with [BsonConstructor] so it is chosen unambiguously.
- Ensure parameter names align with member names or [BsonElement]/serialization names the emitter looks up.
- Remove or mark non-essential members [non-serialized] so the required member set shrinks to a ctor you already have.
Example fix
// before
public class Reward
{
public int Id { get; set; }
public int Count { get; set; }
public Reward() { } // no matching ctor for {Id, Count}
}
// after
public class Reward
{
public int Id { get; set; }
public int Count { get; set; }
[BsonConstructor]
public Reward(int id, int count) { Id = id; Count = count; }
} Defensive patterns
Strategy: type-guard
Validate before calling
// in a test, attempt emission of a sample instance to surface ctor issues early
var emitter = new CSharpObjectCodeEmitter();
try { emitter.Emit(sampleInstance); }
catch (NotSupportedException ex) { Assert.Fail(ex.Message); } Type guard
static bool HasReconstructableCtor(Type t)
{
// a public ctor exists whose parameter names/types cover all public settable members
var memberNames = t.GetFields().Select(f => f.Name).ToHashSet(StringComparer.OrdinalIgnoreCase);
return t.GetConstructors().Any(c =>
c.GetParameters().All(p => p.IsOptional || memberNames.Contains(p.Name)));
} Prevention
- Keep one canonical reconstructing constructor per exported class and annotate it [BsonConstructor].
- Match constructor parameter names to member names (case-insensitive) and exact types.
- Add a test that emits a sample of every exported type.
When it happens
Trigger: A serialized class has only a parameterless constructor but requires member-initialized reconstruction; the constructor parameter names do not match the member/serialization names; parameter types differ (e.g. member is long, ctor takes int); multiple candidate constructors exist and none is annotated with [BsonConstructor].
Common situations: Adding required (non-default) fields to a record-like config class without updating the constructor; renaming a member but not the matching ctor parameter; using init-only properties the emitter cannot supply via the ctor.
Related errors
- 不支持导出 UnityEngine.Object 类型: {runtimeType.FullName}
- 无法为类型 {type.FullName} 生成稳定排序键
- 检测到循环引用,类型: {runtimeType.FullName}
- condition number parse error: {text}
- condition token error at {this.index}: {c}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/db59a882c5395486.
Report an issue: GitHub.