Instances size shouldn't be too big
Types where SizeOfInst > 128 might degrade performance if many instances are created, and can be hard to maintain. A large SizeOfInst may come from a base class rather than many own fields.
WPF/WindowsForm forms and controls, Entity Framework classes, and base classes implying large instances (System.ComponentModel, System.Xml, DevExpress…) are not matched; add other vendors as needed. SizeOfInst metric: https://www.ndepend.com/docs/code-metrics#SizeOfInst
WPF/WindowsForm forms and controls, Entity Framework classes, and base classes implying large instances (System.ComponentModel, System.Xml, DevExpress…) are not matched; add other vendors as needed. SizeOfInst metric: https://www.ndepend.com/docs/code-metrics#SizeOfInst
How to fix
Group the data held directly into smaller composable types.
Severity: linear from Medium (128 bytes) to twice High (2048 bytes) per instance. Annual interest is 10x higher for structures: each time a large structure value is passed as parameter it gets copied, so such a structure should be declared as class.
Severity: linear from Medium (128 bytes) to twice High (2048 bytes) per instance. Annual interest is 10x higher for structures: each time a large structure value is passed as parameter it gets copied, so such a structure should be declared as class.
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Instances size shouldn't be too big</Name>
// <Id>ND1309:InstancesSizeShouldntBeTooBig</Id>
warnif count > 0 from t in JustMyCode.Types where
t.SizeOfInst > 256 &&
// You might want to restrict this rule only on structure, since the cost of copying instance data at each method call might be prohibitive
(t.IsStructure || t.IsClass) &&
// Discard types that represent WPF, WindowsForm and ASP.NET forms and controls and EntityFramwork classes.
t.BaseClasses.All(bc => !bc.ParentNamespace.Name.StartsWithAny(
"Microsoft.AspNetCore", "System.Windows", "System.Web.UI", "System.Web", "Microsoft.EntityFramework",
// Discard types related to these namespaces that typically require large instances size
"System.ComponentModel", "System.Xml",
// Just add more component vendors here if needed
"DevExpress", "Lucene"))
orderby t.SizeOfInst descending
select new {
t,
t.SizeOfInst,
t.InstanceFields,
t.BaseClasses,
instanceKind = t.IsStructure ? "A value" : "An instance",
Debt = t.SizeOfInst.Linear(128,10, 2048, 120).ToMinutes().ToDebt(),
// The annual interest varies linearly from interests for severity Medium for 64 bytes per instance
// to twice interests for severity High for 2048 bytes per instance
AnnualInterest = (t.SizeOfInst.Linear(128, Severity.Medium.AnnualInterestThreshold().Value.TotalMinutes,
2048, 2*(Severity.High.AnnualInterestThreshold().Value.TotalMinutes))
)*(t.IsStructure ? 10 : 1) // Multiply interest by 10 for structures
.ToMinutes().ToAnnualInterest()
}
//<Expl>
// {4} of the *{0}* has a memory footprint of at least *{1} bytes*.
// If this type is often instantiated at runtime this can be problematic.
//</Expl>
//<Desc>
// Types where *SizeOfInst > 128* might degrade performance if many instances
// are created, and can be hard to maintain. A large *SizeOfInst* may come
// from a base class rather than many own fields.
//
// WPF/WindowsForm forms and controls, Entity Framework classes, and base
// classes implying large instances (*System.ComponentModel*, *System.Xml*,
// *DevExpress*…) are not matched; add other vendors as needed.
// *SizeOfInst* metric: https://www.ndepend.com/docs/code-metrics#SizeOfInst
//</Desc>
//<HowToFix>
// Group the data held *directly* into smaller composable types.
//
// Severity: linear from **Medium** (128 bytes) to twice **High** (2048
// bytes) per instance. Annual interest is 10x higher for structures: each
// time a large structure *value* is passed as parameter it gets copied, so
// such a structure should be declared as class.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Design: all 16 items
- Avoid custom delegates ND1300
- Types with disposable instance fields must be disposable ND1301
- Disposable types with unmanaged resources should declare finalizer ND1302
- Methods that create disposable object(s) and that don't call Dispose() ND1303
- Disposable Types Must Unsubscribe Events ND1315
- Classes that are candidate to be turned into structures ND1304
- Avoid namespaces with few types ND1305
- Nested types should not be visible ND1306
- Declare types in namespaces ND1307
- Empty static constructor can be discarded ND1308
- Instances size shouldn't be too big ND1309
- Attribute classes should be sealed ND1310
- Don't use obsolete types, methods or fields ND1311
- Do implement methods that throw NotImplementedException ND1312
- Override equals and operator equals on value types ND1313
- Boxing/unboxing should be avoided ND1314