How to pass objects into an attribute constructor
The values into attributes are limited to simple types; for example, basic constants (including strings) and typeof
... you can't use new
or other more complex code. In short; you can't do this. You can give it the type though:
[PropertyValidation(typeof(NullOrEmptyValidatorScheme)]
i.e. the PropertyValidation
ctor takes a Type
, and use Activator.CreateInstance
inside the code to create the object. Note that you should ideally just store the string internally (AssemblyQualifiedName
).
From ECMA 334v4:
§24.1.3 Attribute parameter types
The types of positional and named
parameters for an attribute class are
limited to the attribute parameter
types, which are:
- One of the following types:
bool
,byte
,char
,
double
,float
,int
,long
,short
,string
.- The type
object
.- The type
System.Type
.- An enum type, provided it has public accessibility and the
types in which it is nested (if any)
also have public accessibility.- Single-dimensional arrays of the above
types.
and
§24.2 Attribute specification
...
An expression
E
is an
attribute-argument-expression if all
of the following statements are true:
- The type of
E
is an attribute
parameter type (§24.1.3).- At compile-time, the value of E can be
resolved to one of the following:
- A constant value.
- A typeof-expression (§14.5.11) specifying a non-generic
type, a closed constructed type
(§25.5.2), or an unbound generic type
(§25.5).- A one-dimensional array of
attribute-argument-expressions.
Pass instance of Class as parameter to Attribute constructor
That's totally impossible. Attributes are baked into the metadata of the assembly at compile-time so talking about passing an instance of a class to an attribute doesn't make any sense because instances exist only at runtime.
On the other hand attributes are always consumed by reflection, so I guess that at the moment you are checking for the presence of this custom attribute on the class metadata you could use the the instance.
Passing an array of objects to Attribute constructor
It's because an array of string
is a compile-time constant whereas an array of Person
is not. This isn't a bug, it's a limitation. The best way around it, that I've found, is by using reflection to set the attributes properties on creation of the object - but it's not pretty.
C# how to extend and pass a parameter to an attribute
It’s not clear what you want to do with the data. You don’t have this type’s instance at the time you create the attribute. This attribute isn’t an instance of an object so you cannot pass any arguments so you must create the object at runtime, and you can do so with reflection.
You can use:
IItemsSource myObject = Activator.CreateInstance<IItemsSource>(obj1, obj2,...);
Update:
As I understand, you want to pass the type and then values to add to the list so you could add
public interface IItemsSource
{
List<string> GetValues();
}
class ItemsSourceAttribute : Attribute
{
public IItemsSource Instance { get; set; }
public ItemsSourceAttribute(Type type, params string[] listParams)
{
if (!typeof(IItemsSource).IsAssignableFrom(type))
throw new ArgumentException($"IItemsSource is not assignable from {type.Name}.");
Instance = (IItemsSource) Activator.CreateInstance(type, listParams);
}
}
public class MyCustomItemsSource : IItemsSource
{
private List<string> _privateList;
public MyCustomItemsSource(params string[] list)
{
_privateList = list.ToList();
}
public List<string> GetValues()
{
// _privateList will start with a value of [abc, 123], as we passed on the constructor.
_privateList.Add("test");
// now [abc, 123, test]
return _privateList;
}
}
And then you could add items to the list like that:
[ItemsSource(typeof(MyCustomItemsSource), "abc", "123"]
Hopefully I got it right. Please comment if you need any adjustments. I wrote this without testing as I'm not with VS on this machine at this moment.
How to get constructor named arguments from attribute
Currently all your parameters are positional ones, so they are returned in ConstructorArguments
.
As written in the docs:
Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.
Changing your MenuItemAttribute
to for example:
public class MenuItemAttribute : Attribute
{
ApplicationCategoryEnum ApplicationCategory { get; }
public string ControllerDisplayName { get; set; }
public bool IsDefaultRoute { get; set; }
public MenuItemAttribute(ApplicationCategoryEnum applicationCategory)
{
ApplicationCategory = applicationCategory;
}
}
And usage
[MenuItem(ApplicationCategoryEnum.CONTROLPANEL, ControllerDisplayName = "asdsa", IsDefaultRoute = true)]
Will give you 2 elements in NamedArguments
collection.
How to pass an instance of a class into attributes within its constructor and have those attributes access initialized attributes?
You want to pass self
(the instance of Foo
being initialized) to Bar
and Baz
, not the class Foo
itself.
class Foo(object):
a=9
def __init__(self):
self.bar = Bar(self)
self.baz = Baz(self)
If this is correct, then running your code should produce the output 72
.
Passing attributes and methods of object inside another object
It's not totally clear, but I think this is what you want:
class PrimaryClass:
def __init__(self, param1, param2):
self.attr1 = param1
self._attr2 = do_something(param2)
def primary_method(self):
sec_cls = SecondaryClass(self)
sec_cls.secondary_method()
def __private_method(self):
do_something_else()
class SecondaryClass:
def __init__(self, primary):
self.primary = primary
def secondary_method():
print(self.primary.attr1)
print(self.primary._attr2)
To hide SecondaryClass
from users of primary_module
, use:
from secondary_module import SecondaryClass as _SecondaryClass
See Hide external modules when importing a module (e.g. regarding code-completion)
Related Topics
Why Is Double.Nan Not Equal to Itself
Visual Studio 2005 Designer Moves Controls and Resizes Form
Wpf Textblock Memory Leak When Using Font
Deserialize JSON String to Dictionary<String,Object>
Update Requires a Valid Updatecommand When Passed Datarow Collection with Modified Rows
How to Find Control in Edit Item Template
How to Have an Optional Parameter for an ASP.NET Soap Web Service
C#6.0 String Interpolation Localization
Wpf Dispatcher {"The Calling Thread Cannot Access This Object Because a Different Thread Owns It."}
How to Scroll to Element in Uwp
ASP.NET C# Static Variables Are Global
Httpwebrequest Times Out on Second Call
Looking for C# Equivalent of Scanf