-
Notifications
You must be signed in to change notification settings - Fork 90
Unclear documentation of supported attribute array types #1299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
using System;
class UhAttribute : Attribute
{
public UhAttribute(string[] p) {}
}
[Uh(new string[] {"foo", "bar"})]
class N{} |
I was able to repro when the argument becomes an element of a using System;
class UhAttribute : Attribute
{
public UhAttribute(params object[] p) {}
}
[Uh(new string[] {"foo", "bar"})]
class N{}
As a workaround, you can write: [Uh(new object[] { new string[] {"foo", "bar"} })] |
However, array type covariance doesn't work in attribute arguments. If the parameter type is |
Ah, I see, the using System;
class UhAttribute : Attribute
{
public UhAttribute(object[] p) {}
}
// Infers string[], which is not allowed
[Uh(new[] {"foo", "bar"})]
class N{} Instead, you can use collection expressions (if on langversion 12+) which builds an // Infers object[], which is allowed
[Uh(["foo", "bar"])] Or, explicitly write the type of the array: // Explicitly specifies object[], which is allowed
[Uh(new object[] { "foo", "bar" })] |
Updated the description. I observe the faulty behavior on the InlineData attribute on xUnit. new int[]{...} works but not new string[]{...} |
In this case using System;
class UhAttribute : Attribute
{
public UhAttribute(params object[] p) {}
}
[Uh(new int[] {1,2})]
class N{} there is no conversion from int[] to object[] so the compiler treats it as meaning |
Previous discussion in #268. |
Note that in xUnit the argument of InlineData expects object[] because they map each entry in the object array to a single parameter in the test case. When someone passes a new string[]{"foo","bar,"} this is not supposed to mean 2 entries in the object [], just one that has the type string[] in the test function. We are also supposed to be able to pass in additional arguments before and after the string[]. For example: It works fine with int[], but fails with string[]. |
AFAICT this works already. SharpLab using System;
public class InlineDataAttribute:Attribute {
public InlineDataAttribute(params object?[] p){}
}
public class C{
[InlineData(new string[]{"foo"}, new string[]{"bar"}, false)]
public void Test(string[] x, string[] y, bool z){}
} |
adding @jaredpar I checked older versions of the spec, and this language hasn't changed since v1. I didn't check the earlier compiler for its behavior. Jared, should this be a spec change, or is this is bug in roslyn? (Happy to make the spec change since this is long standing behavior.) |
If this were a bug in Roslyn, then how could it be fixed? Given
|
Uh oh!
There was an error while loading. Please reload this page.
Type of issue
Spec incorrect
Description
I wanted to provide some feedback regarding section 22.2.4 of the C# specification, which outlines the supported types for attribute parameters. While the documentation mentions "single-dimensional arrays of the above types" as valid attribute parameter types, it doesn't explicitly clarify that arrays of reference types like string are treated differently by the compiler in certain scenarios.
For example, while new int[] {1, 2} works fine as an attribute argument, new string[] {"foo", "bar"} produces the error "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type." This behavior stems from how the compiler handles arrays of reference types versus primitive types in constant expressions.
It would be helpful if the documentation explicitly stated that single-dimensional arrays of reference types (such as string, object, and System.Type) are subject to limitations when used as attribute arguments, even if they are technically valid attribute parameter types.
Thank you for considering this feedback to improve clarity in the C# documentation!
UPDATE: Apologies for missing an important fact. This reproduces when using the Online data attribute on xUnit. It does takes the parameters as an object[].
Page URL
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes?source=docs#2224-attribute-parameter-types
Content source URL
https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/attributes.md
The text was updated successfully, but these errors were encountered: