Type t = typeof(obj1);
if (t == typeof(int))
// Some code here
මෙය දෝෂයකි. C # හි යතුරු ලියන ක්රියාකරුට ගත හැක්කේ වස්තු නොව වර්ග නාම පමණි.
if (obj1.GetType() == typeof(int))
// Some code here
මෙය ක්රියාත්මක වනු ඇත, නමුත් සමහර විට ඔබ බලාපොරොත්තු වන පරිදි නොවේ. වටිනාකම් වර්ග සඳහා, ඔබ මෙහි පෙන්වා ඇති පරිදි, එය පිළිගත හැකි නමුත් යොමු වර්ග සඳහා, එය සත්ය බවට පත්වන්නේ එම වර්ගය හරියටම එකම වර්ගයේ නම් මිස උරුම ධූරාවලියේ වෙනත් දෙයක් නොවේ. උදාහරණයක් වශයෙන්:
class Animal{}
class Dog : Animal{}
static void Foo(){
object o = new Dog();
if(o.GetType() == typeof(Animal))
Console.WriteLine("o is an animal");
Console.WriteLine("o is something else");
}
මෙම මුද්රණය කරන "o is something else"
වර්ගය නිසා o
ය Dog
, නැත Animal
. කෙසේ වෙතත්, ඔබ පන්තියේ IsAssignableFrom
ක්රමය භාවිතා කරන්නේ නම් ඔබට මෙම කාර්යය කළ හැකිය Type
.
if(typeof(Animal).IsAssignableFrom(o.GetType())) // note use of tested type
Console.WriteLine("o is an animal");
මෙම තාක්ෂණය තවමත් විශාල ගැටලුවක්ව පවතී. ඔබගේ විචල්යය ශුන්ය නම්, ඇමතුම GetType()
NullReferenceException එකක් දමනු ඇත. එබැවින් එය නිවැරදිව ක්රියාත්මක කිරීම සඳහා, ඔබ කරන්නේ:
if(o != null && typeof(Animal).IsAssignableFrom(o.GetType()))
Console.WriteLine("o is an animal");
මේ සමඟ, ඔබට යතුරුපදයේ සමාන හැසිරීමක් ඇත is
. එබැවින්, ඔබට අවශ්ය හැසිරීම මෙය නම්, ඔබ is
කියවිය යුතු හා වඩා කාර්යක්ෂම වන යතුරු පදය භාවිතා කළ යුතුය .
if(o is Animal)
Console.WriteLine("o is an animal");
බොහෝ අවස්ථාවන්හීදී, is
මූලික පදය තවමත් ඔබට සැබවින්ම අවශ්ය දේ නොවේ, මන්ද සාමාන්යයෙන් වස්තුවක් එක්තරා ආකාරයක බව දැන ගැනීම පමණක් ප්රමාණවත් නොවේ. සාමාන්යයෙන්, ඔබට ඇත්ත වශයෙන්ම එම වස්තුව එම වර්ගයේ නිදසුනක් ලෙස භාවිතා කිරීමට අවශ්ය වන අතර, එය ද වාත්තු කිරීම අවශ්ය වේ. ඒ නිසා ඔබ මේ වගේ කේත ලිවීම සොයාගත හැකිය:
if(o is Animal)
((Animal)o).Speak();
නමුත් එමඟින් සීඑල්ආර් වස්තුවේ වර්ගය දෙවරක් පරීක්ෂා කරයි. එය is
ක්රියාකරු තෘප්තිමත් කිරීම සඳහා වරක් එය පරික්ෂා කරනු ඇති අතර , o
ඇත්ත වශයෙන්ම එය නම් Animal
, වාත්තු කිරීම වලංගු කිරීම සඳහා අපි එය නැවත පරීක්ෂා කරමු.
ඒ වෙනුවට මෙය කිරීම වඩාත් කාර්යක්ෂම වේ:
Animal a = o as Animal;
if(a != null)
a.Speak();
මෙම as
ක්රියාකරු වෙනුවට නැවත, එය අපොහොසත් වන්නේ නම්, ව්යතිරේකයක් විසි නොවන බව ඉතා අයගේ ක්රමය null
. මේ ආකාරයෙන්, සීඑල්ආර් වස්තුවේ වර්ගය එක් වරක් පමණක් පරීක්ෂා කරන අතර, ඉන් පසුව, අප විසින් ශුන්ය පරීක්ෂණයක් කළ යුතු අතර එය වඩාත් කාර්යක්ෂම වේ.
නමුත් පරෙස්සම් වන්න: බොහෝ අය උගුලකට හසු වේ as
. එය ව්යතිරේකයන් නොදක්වන නිසා, සමහර අය එය "ආරක්ෂිත" කාස්ට් එකක් ලෙස සිතන අතර, ඔවුන් එය තනිකරම භාවිතා කරයි. මෙය මෙවැනි දෝෂ වලට තුඩු දෙයි:
(o as Animal).Speak();
මෙම අවස්ථාවේ දී, සංවර්ධකයා පැහැදිලිවම උපකල්පනය කරන්නේ o
එය සැමවිටම එකක් වනු ඇති Animal
අතර ඔවුන්ගේ උපකල්පනය නිවැරදිව පවතින තාක් කල් සියල්ල හොඳින් ක්රියාත්මක වන බවයි. නමුත් ඔවුන් වැරදියි නම්, ඔවුන් මෙහි අවසන් වන්නේ අ NullReferenceException
. නිතිපතා වාත්තු කිරීමක් සමඟ, ඔවුන් ඒ InvalidCastException
වෙනුවට ලබා ගනු ඇත, එමඟින් ගැටළුව වඩාත් නිවැරදිව හඳුනා ගනු ඇත.
සමහර විට, මෙම දෝෂය සොයා ගැනීම දුෂ්කර විය හැකිය:
class Foo{
readonly Animal animal;
public Foo(object o){
animal = o as Animal;
}
public void Interact(){
animal.Speak();
}
}
මෙය සෑම අවස්ථාවකදීම සංවර්ධකයා පැහැදිලිවම අපේක්ෂා o
කරන තවත් Animal
අවස්ථාවකි, නමුත් as
වාත්තු භාවිතා කරන ඉදිකිරීම්කරු තුළ මෙය පැහැදිලිව පෙනෙන්නට නැත . ක්ෂේත්රය ධනාත්මකව පවරනු ඇතැයි අපේක්ෂා කරන Interact
ක්රමයට ඔබ පිවිසෙන තුරු එය පැහැදිලිව පෙනෙන්නට නැත animal
. මෙම අවස්ථාවේ දී, ඔබ නොමඟ යවන ව්යතිරේකයකින් අවසන් වනවා පමණක් නොව, සත්ය දෝෂය සිදුවූ කාලයට වඩා බොහෝ කලකට පසුව එය විසි නොකරයි.
සාරාංශයකින්:
වස්තුවක් කිසියම් වර්ගයකද නැද්ද යන්න ඔබට දැන ගැනීමට අවශ්ය නම් භාවිතා කරන්න is
.
ඔබට යම් වස්තුවක් එක්තරා ආකාරයක නිදසුනක් ලෙස සැලකීමට අවශ්ය නම්, නමුත් එම වස්තුව එම වර්ගයට අයත් වනු ඇතැයි ඔබ නිශ්චිතව නොදන්නේ නම්, භාවිතා as
කර පරීක්ෂා කරන්න null
.
ඔබට යම් වස්තුවක් එක්තරා ආකාරයක නිදසුනක් ලෙස සැලකීමට අවශ්ය නම් සහ එම වස්තුව එම වර්ගයට අයත් යැයි සිතිය හැකි නම්, සාමාන්ය වාත්තු කිරීමක් භාවිතා කරන්න.
as
එපා!