जरूरत है यहाँ जवाब की समीक्षा करने, और अपने आप को चारों ओर एक छोटे से खेलने के बाद है, मैं ऊपर आ गए हैं निम्नलिखित कार्यान्वयन के साथ, जो जांचता है समय संकलित करने के बजाए रनटाइम पर बाधाएं।
// This example takes 3 parameters...
public class GenericConstraint<T1, T2, T3>
{
public GenericConstraint(Type type)
{
if (!(type is T1) || !(type is T2) || !(type is T3))
{
throw new Exception("This is not a supported type");
}
}
}
अब मैं इसे अपने कस्टम वर्ग से प्राप्त करता हूं ...
Custom<long> item = new Custom<long>();
यह नहीं करता है:
public class Custom<T> : GenericConstraint<string, int, byte>
{
public Custom() : base(typeof(T))
{
}
}
यह अब एक त्रुटि फेंकता है!
Custom<byte> item2 = new Custom<byte>();
जैसा कि मार्क ग्रेवेल ने कहा है, यह विरासत या जेनेरिक का अच्छा उपयोग नहीं है। जेनेरिककोनस्ट्रेन को विरासत में रखते हुए, इस तर्कसंगत रूप से सोचते हुए, यह केवल विरासत को सीमित कर रहा है, और टाइप पदानुक्रम का सही उपयोग नहीं कर रहा है। जेनेरिक के उपयोग के संदर्भ में, यह वास्तव में सुंदर व्यर्थ है!
इसलिए मेरे पास एक और समाधान है जो रनटाइम पर प्रकारों को बाधित करने के लिए एक सहायक विधि के रूप में कार्य करता है। यह वस्तु को विरासत से मुक्त करता है और इसलिए प्रकार पदानुक्रम पर कोई प्रभाव नहीं पड़ता है।
public static void ConstrainParameterType(Type parameterType, GenericConstraint constraintType, params Type[] allowedTypes)
{
if (constraintType == GenericConstraint.ExactType)
{
if (!allowedTypes.Contains<Type>(parameterType))
{
throw new Exception("A runtime constraint disallows use of type " + parameterType.Name + " with this parameter.");
}
}
else
{
foreach (Type constraint in allowedTypes)
{
if (!constraint.IsAssignableFrom(parameterType))
{
throw new Exception("A runtime constraint disallows use of type " + parameterType.Name + " with this parameter.");
}
}
}
}
public enum GenericConstraint
{
/// <summary>
/// The type must be exact.
/// </summary>
ExactType,
/// <summary>
/// The type must be assignable.
/// </summary>
AssignableType
}
यह अब सामान्य वस्तुओं पर कई प्रकार की कमी की अनुमति देता है, यहां तक कि जहां प्रकार सील कर रहे हैं आदि
"public class Custom where T : string ... is not allowed, because the only T that meets that is: string (string is sealed) - making it rather pointless as a generic."
हाँ, यह व्यर्थ है, लेकिन कुछ परिस्थितियों में, आप के लिए एक वस्तु विवश करना चाह सकते हैं उदाहरण के लिए अनुमति दें; स्ट्रिंग, स्ट्रिंगबिल्डर और सिक्योरस्टिंग। हालांकि यह संकलन समय बाधा प्रदान नहीं करता है, यह रनटाइम बाधा प्रदान करता है, और कुछ लचीलापन किस प्रकार बाधा में उपयोग किया जा सकता है।
सबसे अच्छा आप इन स्थितियों के लिए वास्तव में कर सकते हैं एक रैपर वर्ग बनाते हैं, या कुछ और सामान्य (ऑब्जेक्ट) लेते हैं और कन्स्ट्रक्टर में टाइप-चेकिंग करते हैं। क्या यह सुंदर है? नहीं। क्या यह काम करेगा? हाँ। – sybkar
@ सब्बर, क्या आपका मतलब मेरे उत्तर में है? – series0ne