Reputation: 3
How do I create a class instance using known attributes? In this the attributes are values of an enum.
public enum MyEnum
{
Value1,
Value2
}
class MyAttribute : Attribute... //attribute definition class
{ //uses the enum}
//Main
abstract class MyMain ...
{
public static MyMain CreateClass
{
MyMain newInheritedClass = ?
}
}
[MyAttribute(MyEnum.Value1)]
class MyClassA : MyMain ...
[MyAttribute(MyEnum.Value2)]
class MyClassB : MyMain ...
Upvotes: 0
Views: 1964
Reputation: 32445
For the purposes you describe in comments I think using attributes is little bid overkill.
Just create a static method or factory class with method which will do the same things:
public static MyMain CreateInstance(MyEnum attribute)
{
if(attribute == MyEnum.Value1)
{
return new MyClassA();
}
else
{
//...
}
}
Of course if you have a task to create instance based on the attributes then:
private readonly Dictionary<MyEnum, Type> _Data;
public Factory(Assembly assembly)
{
var myAttributeClasses =
assembly.GetTypes()
.Select(t => new
{
DirevedType = t,
Attribute = (MyAttribute)t.GetCustomAttribute(typeof(MyAttribute))
})
.Where(data => data.Attribute != null);
_Data = new Dictionary<MyEnum, Type>();
foreach(var data in myAttributeClasses)
{
_Data.Add(data.Attribute.EnumValue, data.DerivedType);
}
}
public MyMain CreateInstance(MyEnum enumvalue)
{
Type derivedType;
if(_Data.TryGetValue(enumvalue, out derivedType) == false)
return null;
return Activator.CreateInstance(derivedType);
}
Upvotes: 0
Reputation: 32740
I competely agree with Fabio's answer in that using attributes seems an overkill here but we don't have enough information to really know why you are using this approach so I'll show you how it would be done:
Your method CreateClass
should look like this:
public static MyMain CreateClass(MyEnum value)
{
var targetType = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(MyMain)) &&
t.GetCustomAttribute<MyAttribute>()?.Value == value)
.FirstOrDefault();
if (targetType != null)
return Activator.CreateInstance(targetType) as MyMain;
return null;
}
This presuposes two things:
If niether is the case you can still adapt the solution investigating a little.
Upvotes: 2