सबसे पहले, अपनी विशेषता घोषित करने और अपनी कक्षाओं में जोड़ें।
enum MyEnum
{
Undefined,
Set,
Reset
}
class MyEnumAttribute : Attribute
{
public MyEnumAttribute(MyEnum value)
{
Value = value;
}
public MyEnum Value { get; private set; }
}
[MyEnum(MyEnum.Reset)]
class ResetClass
{
}
[MyEnum(MyEnum.Set)]
class SetClass
{
}
[MyEnum(MyEnum.Undefined)]
class UndefinedClass
{
}
फिर, आप इस कोड का उपयोग अपने enums और प्रकारों के साथ एक शब्दकोश बनाने के लिए कर सकते हैं, और गतिशील रूप से एक प्रकार का निर्माण कर सकते हैं।
//Populate a dictionary with Reflection
var dictionary = Assembly.GetExecutingAssembly().GetTypes().
Select(t => new {t, Attribute = t.GetCustomAttribute(typeof (MyEnumAttribute))}).
Where(e => e.Attribute != null).
ToDictionary(e => (e.Attribute as MyEnumAttribute).Value, e => e.t);
//Assume that you dynamically want an instance of ResetClass
var wanted = MyEnum.Reset;
var instance = Activator.CreateInstance(dictionary[wanted]);
//The biggest downside is that instance will be of type object.
//My solution in this case was making each of those classes implement
//an interface or derive from a base class, so that their signatures
//would remain the same, but their behaviors would differ.
आप शायद नोटिस सकते हैं, Activator.CreateInstance
बुला performant नहीं है। इसलिए, यदि आप प्रदर्शन को थोड़ा सुधारना चाहते हैं, तो आप शब्दकोश को Dictionary<MyEnum,Func<object>>
में बदल सकते हैं और प्रकारों को मानों के रूप में जोड़ने के बजाय आप अपनी प्रत्येक कक्षा के निर्माता को लपेटकर और उन्हें ऑब्जेक्ट्स के रूप में वापस करने के कार्यों को जोड़ देंगे।
EDIT: मैं this पृष्ठ से अनुकूलित ConstructorFactory
कक्षा जोड़ रहा हूं।
static class ConstructorFactory
{
static ObjectActivator<T> GetActivator<T>(ConstructorInfo ctor)
{
var paramsInfo = ctor.GetParameters();
var param = Expression.Parameter(typeof(object[]), "args");
var argsExp = new Expression[paramsInfo.Length];
for (var i = 0; i < paramsInfo.Length; i++)
{
Expression index = Expression.Constant(i);
var paramType = paramsInfo[i].ParameterType;
Expression paramAccessorExp = Expression.ArrayIndex(param, index);
Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType);
argsExp[i] = paramCastExp;
}
var newExp = Expression.New(ctor, argsExp);
var lambda = Expression.Lambda(typeof(ObjectActivator<T>), newExp, param);
var compiled = (ObjectActivator<T>)lambda.Compile();
return compiled;
}
public static Func<T> Create<T>(Type destType)
{
var ctor = destType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).First();
Func<ConstructorInfo, object> activatorMethod = GetActivator<Type>;
var method = typeof(ConstructorFactory).GetMethod(activatorMethod.Method.Name, BindingFlags.Static | BindingFlags.NonPublic);
var generic = method.MakeGenericMethod(destType);
dynamic activator = generic.Invoke(null, new object[] { ctor });
return() => activator();
}
delegate T ObjectActivator<out T>(params object[] args);
}
आप Activator.CreateInstance
के लिए एक विकल्प के रूप में उपयोग कर सकते हैं, यह अधिक से अधिक प्रदर्शन करता है, तो परिणाम कैश किया गया है प्रदान करता है।
var dictionary = Assembly.GetExecutingAssembly().GetTypes().
Select(t => new { t, Attribute = t.GetCustomAttribute(typeof(MyEnumAttribute)) }).
Where(e => e.Attribute != null).
ToDictionary(e => (e.Attribute as MyEnumAttribute).Value,
e => ConstructorFactory.Create<object>(e.t));
var wanted = MyEnum.Reset;
var instance = dictionary[wanted]();
क्या आप 2 बार 2 स्थिति (2 एनम मूल्यों के साथ स्विच में स्विच) के साथ समस्या का वर्णन कर सकते हैं? –
मुझे लगता है कि अगर आप सबक्लास पर विशेषताओं का उपयोग करते हैं, तो आपको इसका उपयोग करना होगा स्विच में स्विच में स्विच। मो फिर से आपको सभी उप-वर्गों के लिए विशेषता मान प्राप्त करने के लिए प्रतिबिंब का उपयोग करना होगा और जो धीमा होगा। – 24x7Programmer