Skip to content

Commit 668cc30

Browse files
authored
Add errors and warnings related to the dynamic type and dynamic binding (#49432)
* framework for next PR * Add all undocumented errors * reorganized by themes. * fix incorrect messages. * first edit pass. * final proofread. * fix incorrect recommendation on packages * Fix warnings and errors * one more set of warnings
1 parent a7d611a commit 668cc30

File tree

4 files changed

+270
-31
lines changed

4 files changed

+270
-31
lines changed

.github/prompts/error-consolidation.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ Overall steps:
88
1. Run Copilot search for other existing errors that person may have missed.
99
1. Search for missing errors.
1010

11-
## Add a single existing file into the new consolidated article.
11+
## Add a single existing file into the new consolidated article.
1212

13-
We're going to work through a series of files consolidating errors and warnings related to declaring overloaded operators.
13+
We're going to work through a series of files consolidating errors and warnings related to declaring the `dynamic` type and dynamic binding.
1414

15-
The destination for all these edits is the overloaded-operator-errors.md file. It already contains a skeleton for the final output.
15+
The destination for all these edits is the dynamic-type-and-binding-errors.md file. It already contains a skeleton for the final output.
1616

1717
For each source file I specify in this chat, you'll do the following tasks:
1818

@@ -28,7 +28,7 @@ For each source file I specify in this chat, you'll do the following tasks:
2828

2929
## Search for other related articles that may be missed.
3030

31-
Search all files in the docs/csharp/language-reference/compiler-messages and the docs/csharp/misc folder for any other errors and warnings that involve operator overloading. Give me a list to review for possible additional consolidation. Don't make any edits until the originating user approves.
31+
Search all files in the docs/csharp/language-reference/compiler-messages and the docs/csharp/misc folder for any other errors and warnings that involve the `dynamic` type or dynamic binding. Give me a list to review for possible additional consolidation. Don't make any edits until the originating user approves.
3232

3333
## Final search in roslyn source
3434

@@ -51,7 +51,7 @@ Note that no redirections need to be added for these error codes.
5151

5252
## Build consolidated sections
5353

54-
For all remaining work, all edits will be in the `overloaded-operator-errors.md` file. The final format should mirror the structure of the `preprocessor-errors.md` file. Every H2 is a theme, all anchors are for the theme, not an individual error code.
54+
For all remaining work, all edits will be in the `dynamic-type-and-binding-errors.md` file. The final format should mirror the structure of the `preprocessor-errors.md` file. Every H2 is a theme, all anchors are for the theme, not an individual error code.
5555

5656
To do that, make a new H2 section for the theme. Remove all the H2s for the individual error codes that are part of that theme. Where applicable, the new H2 can include text or examples from the H2s you remove. The new section should include links to language reference articles that discuss the feature or theme.
5757

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
---
2+
title: Resolve errors related to dynamic binding and the dynamic type
3+
description: These errors indicate an incorrect use of the `dynamic` type or an expression with runtime (or dynamic) binding. Learn about the errors and how to fix them.
4+
f1_keywords:
5+
- "CS1962"
6+
- "CS1964"
7+
- "CS1965"
8+
- "CS1966"
9+
- "CS1967"
10+
- "CS1968"
11+
- "CS1969"
12+
- "CS1970"
13+
- "CS1971"
14+
- "CS1972"
15+
- "CS1973"
16+
- "CS1974"
17+
- "CS1975"
18+
- "CS1976"
19+
- "CS1977"
20+
- "CS1978"
21+
- "CS1979"
22+
- "CS1980"
23+
- "CS1981"
24+
- "CS7083"
25+
- "CS8133"
26+
- "CS8364"
27+
- "CS8416"
28+
- "CS9230"
29+
helpviewer_keywords:
30+
- "CS1962"
31+
- "CS1964"
32+
- "CS1965"
33+
- "CS1966"
34+
- "CS1967"
35+
- "CS1968"
36+
- "CS1969"
37+
- "CS1970"
38+
- "CS1971"
39+
- "CS1972"
40+
- "CS1973"
41+
- "CS1974"
42+
- "CS1975"
43+
- "CS1976"
44+
- "CS1977"
45+
- "CS1978"
46+
- "CS1979"
47+
- "CS1980"
48+
- "CS1981"
49+
- "CS7083"
50+
- "CS8133"
51+
- "CS8364"
52+
- "CS8416"
53+
- "CS9230"
54+
ms.date: 10/23/2025
55+
ai-usage: ai-assisted
56+
---
57+
# Resolve warnings related to the dynamic type and dynamic binding
58+
59+
This article covers the following compiler errors:
60+
61+
<!-- The text in this list generates issues for Acrolinx, because they don't use contractions.
62+
That's be design. The text closely matches the text of the compiler error / warning for SEO purposes.
63+
-->
64+
- [**CS1962**](#using-dynamic-in-type-declarations-and-constraints): *The `typeof` operator cannot be used on the `dynamic` type.*
65+
- [**CS1964**](#dynamic-operation-restrictions): *Cannot apply dynamic conversion to an expression.*
66+
- [**CS1965**](#using-dynamic-in-type-declarations-and-constraints): *Cannot derive from the `dynamic` type.*
67+
- [**CS1966**](#using-dynamic-in-type-declarations-and-constraints): *Cannot derive from a constructed dynamic type.*
68+
- [**CS1967**](#using-dynamic-in-type-declarations-and-constraints): *Cannot use the `dynamic` type as a type constraint.*
69+
- [**CS1968**](#using-dynamic-in-type-declarations-and-constraints): *Cannot use a constructed dynamic type as a type constraint.*
70+
- [**CS1969**](#missing-runtime-support-for-dynamic): *One or more types required to compile a dynamic expression cannot be found.*
71+
- [**CS1970**](#using-dynamic-in-type-declarations-and-constraints): *Do not use '`System.Runtime.CompilerServices.DynamicAttribute`'. Use the '`dynamic`' keyword instead.*
72+
- [**CS1971**](#dynamic-operation-restrictions): *The call to member needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access.*
73+
- [**CS1972**](#dynamic-operation-restrictions): *The indexer access needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access.*
74+
- [**CS1973**](#dynamic-operation-restrictions): *The dynamic argument type does not match the target parameter type for extension method.*
75+
- [**CS1974**](#dynamic-dispatch-warnings): *Dynamic dispatch to a conditional method will fail at runtime.*
76+
- [**CS1975**](#dynamic-operation-restrictions): *The constructor call needs to be dynamically dispatched, but cannot be because it is part of a constructor initializer. Consider casting the dynamic arguments.*
77+
- [**CS1976**](#dynamic-operation-restrictions): *Cannot use a method group as an argument to a dynamically dispatched operation.*
78+
- [**CS1977**](#dynamic-operation-restrictions): *Cannot use a lambda expression as an argument to a dynamically dispatched operation.*
79+
- [**CS1978**](#dynamic-operation-restrictions): *Cannot use an expression as an argument to a dynamically dispatched operation.*
80+
- [**CS1979**](#dynamic-operation-restrictions): *Query expressions with a source or join sequence of type dynamic are not allowed.*
81+
- [**CS1980**](#missing-runtime-support-for-dynamic): *Cannot define a class or member that uses 'dynamic' because the compiler required type is missing.*
82+
- [**CS1981**](#dynamic-dispatch-warnings): *The '`is dynamic`' pattern is misleading. Use '`is object`' instead.*
83+
- [**CS7083**](#missing-runtime-support-for-dynamic): *Expression must be implicitly convertible to '`System.Object`', or the type '`dynamic`' is not available.*
84+
- [**CS8133**](#dynamic-operation-restrictions): *Cannot deconstruct dynamic objects.*
85+
- [**CS8364**](#dynamic-operation-restrictions): *An argument to '`nameof`' cannot use any dynamic operation.*
86+
- [**CS8416**](#dynamic-operation-restrictions): *The async modifier cannot be used in the expression of a dynamic attribute.*
87+
- [**CS9230**](#dynamic-operation-restrictions): *Cannot perform a dynamic invocation on an expression with type.*
88+
89+
## Using `dynamic` in type declarations and constraints
90+
91+
- **CS1962**: *The typeof operator cannot be used on the `dynamic` type.*
92+
- **CS1965**: *Cannot derive from the `dynamic` type.*
93+
- **CS1966**: *Cannot derive from a constructed dynamic type.*
94+
- **CS1967**: *Cannot use the `dynamic` type as a type constraint.*
95+
- **CS1968**: *Cannot use a constructed dynamic type as a type constraint.*
96+
- **CS1970**: *Do not use '`System.Runtime.CompilerServices.DynamicAttribute`'. Use the '`dynamic`' keyword instead.*
97+
98+
The [`dynamic` type](../builtin-types/reference-types.md#the-dynamic-type) provides late binding for operations at runtime. Use concrete types in contexts where the compiler needs type information at compile time, such as type declarations, constraints, inheritance, or reflection operations:
99+
100+
- Use concrete types for reflection operations. Use specific types instead of `dynamic` with the `typeof` operator (CS1962)
101+
- Use concrete types for inheritance. Specify a concrete base class instead of `dynamic` (CS1965, CS1966):
102+
- Use concrete type constraints. Specify concrete type constraints on generic parameters instead of `dynamic` (CS1967, CS1968):
103+
- Use the `dynamic` keyword for variables. Always use the `dynamic` keyword to declare dynamic variables. Don't apply the `DynamicAttribute` directly (CS1970):
104+
105+
For more information about the `dynamic` type and its proper usage, see [Using type dynamic](../../advanced-topics/interop/using-type-dynamic.md).
106+
107+
## Dynamic operation restrictions
108+
109+
- **CS1964**: *Cannot apply dynamic conversion to an expression.*
110+
- **CS1971**: *The call to member needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access.*
111+
- **CS1972**: *The indexer access needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access.*
112+
- **CS1973**: *The dynamic argument type does not match the target parameter type for extension method.*
113+
- **CS1975**: *The constructor call needs to be dynamically dispatched, but cannot be because it is part of a constructor initializer. Consider casting the dynamic arguments.*
114+
- **CS1976**: *Cannot use a method group as an argument to a dynamically dispatched operation.*
115+
- **CS1977**: *Cannot use a lambda expression as an argument to a dynamically dispatched operation.*
116+
- **CS1978**: *Cannot use an expression as an argument to a dynamically dispatched operation.*
117+
- **CS1979**: *Query expressions with a source or join sequence of type dynamic are not allowed.*
118+
- **CS8133**: *Cannot deconstruct dynamic objects.*
119+
- **CS8364**: *An argument to '`nameof`' cannot use any dynamic operation.*
120+
- **CS8416**: *The async modifier cannot be used in the expression of a dynamic attribute.*
121+
- **CS9230**: *Cannot perform a dynamic invocation on an expression with type.*
122+
123+
While [dynamic binding](../operators/member-access-operators.md#member-access-expression-) provides flexibility at runtime, cast dynamic values to specific types when you need compile-time type information for certain operations.
124+
125+
- **Cast dynamic arguments before calling base members:** Cast dynamic arguments to their specific types before calling base members, indexers, or constructors (CS1971, CS1972, CS1975):
126+
127+
```csharp
128+
class Base
129+
{
130+
public virtual void Method(object obj) { }
131+
public virtual int this[int index] => 0;
132+
public Base(int value) { }
133+
}
134+
135+
class Derived : Base
136+
{
137+
public Derived(dynamic value) : base((int)value) { } // Cast before calling base constructor
138+
139+
public override void Method(object obj)
140+
{
141+
dynamic d = obj;
142+
base.Method((object)d); // Cast before calling base method
143+
}
144+
145+
public override int this[int index]
146+
{
147+
get
148+
{
149+
dynamic d = index;
150+
return base[(int)d]; // Cast before accessing base indexer
151+
}
152+
}
153+
}
154+
```
155+
156+
- **Cast to specific types before passing delegates or lambdas:** Cast the dynamic object to its concrete type before passing method groups, lambda expressions, or delegates (CS1976, CS1977, CS1978):
157+
158+
```csharp
159+
dynamic d = GetDynamicObject();
160+
161+
// Avoid:
162+
d.ProcessData(Console.WriteLine); // CS1976
163+
d.ProcessData(x => x * 2); // CS1977
164+
165+
// Recommended:
166+
((IProcessor)d).ProcessData(Console.WriteLine); // Cast first
167+
((IProcessor)d).ProcessData(x => x * 2); // Cast first
168+
```
169+
170+
- **Use concrete types for LINQ queries:** Use a concrete type instead of `dynamic` for LINQ query sources and join sequences (CS1979):
171+
172+
```csharp
173+
dynamic data = GetData();
174+
175+
// Avoid:
176+
var query = from item in data // CS1979
177+
select item;
178+
179+
// Recommended:
180+
IEnumerable<MyType> typedData = data;
181+
var query = from item in typedData
182+
select item;
183+
```
184+
185+
- **Access tuple elements individually:** Access tuple elements individually instead of using deconstruction with dynamic tuples (CS8133):
186+
187+
```csharp
188+
dynamic tuple = (1, 2);
189+
190+
// Avoid:
191+
var (a, b) = tuple; // CS8133
192+
193+
// Recommended:
194+
var a = tuple.Item1;
195+
var b = tuple.Item2;
196+
```
197+
198+
- **Use compile-time expressions for operations requiring type information:** Use concrete types for operations that need compile-time type information (CS1964, CS1973, CS8364, CS8416, CS9230):
199+
200+
```csharp
201+
dynamic value = GetValue();
202+
203+
// Avoid:
204+
var name = nameof(value.Property); // CS8364
205+
206+
// Recommended:
207+
MyType typedValue = value;
208+
var name = nameof(typedValue.Property); // Use concrete type
209+
```
210+
211+
For more information about dynamic binding and its limitations, see [Using type dynamic](../../advanced-topics/interop/using-type-dynamic.md).
212+
213+
## Missing runtime support for dynamic
214+
215+
- **CS1969**: *One or more types required to compile a dynamic expression cannot be found. Are you missing a reference to 'Microsoft.CSharp.dll'?*
216+
- **CS1980**: *Cannot define a class or member that uses 'dynamic' because the compiler required type cannot be found. Are you missing a reference?*
217+
- **CS7083**: *Expression must be implicitly convertible to '`System.Object`', or the type '`dynamic`' is not available.*
218+
219+
The compiler needs types from the `System.Runtime` namespace and the Dynamic Language Runtime (DLR) to generate code for dynamic operations (CS1969, CS1980, CS7083). Ensure your project includes the necessary references. The required types are included in all modern .NET (.NET 5 and later) projects. For .NET Framework projects, add a reference to `Microsoft.CSharp.dll` in your project file.
220+
221+
For more information about dynamic type requirements, see [Using type dynamic](../../advanced-topics/interop/using-type-dynamic.md).
222+
223+
## Dynamic dispatch warnings
224+
225+
- **CS1974**: *The dynamically dispatched call to method can fail at run-time because one or more applicable overloads are conditional methods.*
226+
- **CS1981**: *The '`is dynamic`' pattern is misleading. The runtime type of the subexpression is never '`dynamic`'. Consider using '`object`' instead.*
227+
228+
When you call methods that have the `[Conditional]` attribute, avoid using dynamic dispatch. The compiler can't verify conditional method attributes with dynamic binding, which can cause runtime failures (CS1974). Cast the dynamic expression to its actual type first:
229+
230+
```csharp
231+
dynamic d = GetObject();
232+
233+
// Avoid:
234+
d.ConditionalMethod(); // CS1974 - can fail at runtime
235+
236+
// Recommended:
237+
MyClass obj = (MyClass)d;
238+
obj.ConditionalMethod(); // Compile-time checks ensure correctness
239+
```
240+
241+
When you check whether a value is non-null, use `is object` instead of `is dynamic`. The `dynamic` keyword is a compile-time construct, and no object's runtime type is ever `dynamic` (CS1981):
242+
243+
```csharp
244+
// Avoid:
245+
if (someValue is dynamic) // CS1981 - always evaluates to false
246+
{
247+
// This code never executes
248+
}
249+
250+
// Recommended:
251+
if (someValue is object) // Correctly checks if non-null
252+
{
253+
// This code executes for non-null values
254+
}
255+
```
256+
257+
For more information about dynamic dispatch and runtime behavior, see [Using type dynamic](../../advanced-topics/interop/using-type-dynamic.md).

docs/csharp/language-reference/toc.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,12 @@ items:
619619
- name: Thread synchronization
620620
href: ./compiler-messages/lock-semantics.md
621621
displayName: CS0185, CS9216, CS9217
622+
- name: Dynamic expressions
623+
href: ./compiler-messages/dynamic-type-and-binding-errors.md
624+
displayName: >
625+
CS1962, CS1964, CS1965, CS1966, CS1967, CS1968, CS1969, CS1970, CS1971, CS1972,
626+
CS1973, CS1974, CS1975, CS1976, CS1977, CS1978, CS1979, CS1980, CS1981, CS7083,
627+
CS8133, CS8364, CS8416, CS9230
622628
- name: Unsafe code
623629
href: ./compiler-messages/unsafe-code-errors.md
624630
displayName: >

docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,7 @@ f1_keywords:
3838
- "CS1774"
3939
- "CS1960"
4040
- "CS1961"
41-
- "CS1962"
42-
- "CS1964"
43-
- "CS1965"
44-
- "CS1966"
45-
- "CS1967"
46-
- "CS1968"
47-
- "CS1969"
48-
- "CS1970"
49-
- "CS1971"
50-
- "CS1972"
51-
- "CS1973"
52-
- "CS1974"
53-
- "CS1975"
54-
- "CS1976"
55-
- "CS1977"
56-
- "CS1978"
57-
- "CS1979"
58-
- "CS1980"
59-
- "CS1981"
60-
- "CS1984"
41+
- "CS1982"
6142
- "CS1985"
6243
- "CS1989"
6344
- "CS1991"
@@ -154,8 +135,7 @@ f1_keywords:
154135
- "CS7080"
155136
- "CS7081"
156137
- "CS7082"
157-
- "CS7083"
158-
- "CS7085"
138+
- "CS7084"
159139
- "CS7086"
160140
- "CS7087"
161141
- "CS7088"
@@ -249,7 +229,6 @@ f1_keywords:
249229
- "CS8123"
250230
- "CS8126"
251231
- "CS8128"
252-
- "CS8133"
253232
- "CS8134"
254233
- "CS8135"
255234
- "CS8136"
@@ -306,7 +285,6 @@ f1_keywords:
306285
- "CS8360"
307286
- "CS8361"
308287
- "CS8362"
309-
- "CS8364"
310288
- "CS8372"
311289
- "CS8375"
312290
- "CS8377"
@@ -324,7 +302,6 @@ f1_keywords:
324302
- "CS8413"
325303
- "CS8414"
326304
- "CS8415"
327-
- "CS8416"
328305
- "CS8417"
329306
- "CS8418"
330307
- "CS8419"
@@ -577,7 +554,6 @@ f1_keywords:
577554
- "CS9097"
578555
# C# 12 errors begin here
579556
- "CS9229" # Modifiers cannot be placed on using declarations (using declarations)
580-
- "CS9230" # Cannot perform a dynamic invocation on an expression with type 'type'. (dynamic binding)
581557
# C# 14 errors begin here
582558
- "CS9327"
583559
- "CS9328"

0 commit comments

Comments
 (0)