سؤال

وهذا هو سؤال سخيف، ولكن يمكنك استخدام هذا الرمز لمعرفة ما اذا كان شيء هو نوع معين ...

if (child is IContainer) { //....

هل هناك طريقة أكثر أناقة للتحقق من "NOT" مثلا؟

if (!(child is IContainer)) { //A little ugly... silly, yes I know...

//these don't work :)
if (child !is IContainer) {
if (child isnt IContainer) { 
if (child aint IContainer) { 
if (child isnotafreaking IContainer) { 

نعم، نعم ... سؤال سخيف ....

<القوي> لأن هناك بعض الشكوك في ما يبدو رمز مثل، انها مجرد عودة بسيطة في بداية طريقة.

public void Update(DocumentPart part) {
    part.Update();
    if (!(DocumentPart is IContainer)) { return; }
    foreach(DocumentPart child in ((IContainer)part).Children) {
       //...etc...
هل كانت مفيدة؟

المحلول

if(!(child is IContainer))

وهي المشغل الوحيد للذهاب (لا يوجد مشغل IsNot).

ويمكنك بناء طريقة التمديد الذي تقوم به:

public static bool IsA<T>(this object obj) {
    return obj is T;
}

ومن ثم استخدامه ل:

if (!child.IsA<IContainer>())

وكنت قد اتبع على الموضوع الخاص بك:

public static bool IsNotAFreaking<T>(this object obj) {
    return !(obj is T);
}

if (child.IsNotAFreaking<IContainer>()) { // ...

تحديث (تدرس مقتطف الشفرة إلى OP و):

ومنذ كنت في الواقع يلقي قيمة بعد ذلك، هل يمكن أن مجرد استخدام as بدلا من ذلك:

public void Update(DocumentPart part) {
    part.Update();
    IContainer containerPart = part as IContainer;
    if(containerPart == null) return;
    foreach(DocumentPart child in containerPart.Children) { // omit the cast.
       //...etc...

نصائح أخرى

ويمكنك أن تفعل ذلك بهذه الطريقة:

object a = new StreamWriter("c:\\temp\\test.txt");

if (a is TextReader == false)
{
   Console.WriteLine("failed");
}

لماذا لا تستخدم فقط للآخر؟

if (child is IContainer)
{
  //
}
else
{
  // Do what you want here
}

ولها أنيق مألوفة وبسيطة؟

والطريقة لديك على ما يرام لكنك <م> قد إنشاء مجموعة من طرق الإرشاد لجعل "طريقة أكثر أناقة للتحقق من والمثال" NOT ".

public static bool Is<T>(this object myObject)
{
    return (myObject is T);
}

public static bool IsNot<T>(this object myObject)
{
    return !(myObject is T);
}

وبعد ذلك يمكن أن تكتب:

if (child.IsNot<IContainer>())
{
    // child is not an IContainer
}

والقبيح؟ أنا أعترض. الطريقة الوحيدة الأخرى (وأنا شخصيا أعتقد أن هذا هو "أقبح"):

var obj = child as IContainer;
if(obj == null)
{
   //child "aint" IContainer
}

والمشغل is تقييم إلى نتيجة منطقية، حتى تتمكن من فعل أي شيء من شأنه أن يكون الأمر خلاف ذلك قادرة على القيام به على منطقي. لإبطاله استخدام المشغل !. لماذا تريد أن يكون لها مشغل مختلفة فقط لهذا؟

ووIsNot<T> طريقة التمديد هو وسيلة لطيفة لتمديد بناء الجملة. نضع في اعتبارنا

var container = child as IContainer;
if(container != null)
{
  // do something w/ contianer
}

وأداء أفضل من عدم القيام بأي شيء من هذا القبيل

if(child is IContainer)
{
  var container = child as IContainer;
  // do something w/ container
}

في قضيتك، لا يهم كما كنت عائدا من طريقة. وبعبارة أخرى، يجب الحرص على عدم قيام كلا من الاختيار لنوع ثم نوع التحويل مباشرة بعد.

وعلى الرغم من أن المشغل هو عادة أفضل وسيلة، ولكن هناك بديل التي يمكنك استخدامها في بعض cirumstances. يمكنك استخدام كمشغل واختبار لاغية.

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}

ولئن كان هذا لا تجنب المشكلة من الأقواس، من أجل الناس الوصول إلى هنا عن طريق جوجل، وتجدر الإشارة إلى أن وجود تركيب أحدث (اعتبارا من C # 7) لجعل بقية التعليمات البرمجية نظافة قليلا:

if (!(DocumentPart is IContainer container)) { return; }
foreach(DocumentPart child in container.Children) {
    ...

وهذا يتجنب الصب مزدوج، وخالية الاختيار، وجود متغير متوفر في نطاقات حيث أنها يمكن أن تكون فارغة.

لم يتم ذكر هذا حتى الان. وهو يعمل، وأنا أعتقد أنه يبدو أفضل من استخدام !(child is IContainer)

if (part is IContainer is false)
{
    return;
}
if (child is IContainer ? false : true)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top