لماذا تفشل لممثلين ينق العملية عندما يكون لدي يلقي ضمنيا تعريف؟

StackOverflow https://stackoverflow.com/questions/808725

  •  03-07-2019
  •  | 
  •  

سؤال

ولقد خلق طبقتين، مع واحد منهم وجود يلقي الضمني بينهما:

public class Class1
{
    public int Test1;
}

public class Class2
{
    public int Test2;

    public static implicit operator Class1(Class2 item)
    {
        return new Class1{Test1 = item.Test2};
    }
}

وعندما إنشاء قائمة جديدة من نوع واحد ومحاولة المصبوب إلى أخرى، فإنه فشل مع InvalidCastException:

List<Class2> items = new List<Class2>{new Class2{Test2 = 9}};
foreach (Class1 item in items.Cast<Class1>())
{
    Console.WriteLine(item.Test1);
}

وهذا، ومع ذلك، يعمل بشكل جيد:

foreach (Class1 item in items)
{
    Console.WriteLine(item.Test1);
}

لماذا يلقي الضمني لا يسمى عند استخدام المصبوب

هل كانت مفيدة؟

المحلول

ولأن، النظر في قانون عبر العاكس، يلقي محاولة دويسنت اتخاذ أي مشغلي يلقي ضمنية (رمز المصبوب LINQ هو الأمثل بشدة للحالات الخاصة من جميع الأنواع، ولكن لا شيء في هذا الاتجاه) في الاعتبار (كما العديد من اللغات. NET سوف لا).

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

وتحرير: في والمرافق العامة أكثر تعقيدا مثل الضمني / explict، لا يتم التعامل مع مشغلي المساواة الخ عموما مرافق عامة مثل LINQ

نصائح أخرى

ويمكنك أيضا استخدام هذا للقيام الصب مع التحويلات إذا لزم الأمر:

public static IEnumerable<TDest> CastAll<TItem, TDest>(this IEnumerable<TItem> items)
{
 var p = Expression.Parameter(typeof(TItem), "i");
 var c = Expression.Convert(p, typeof(TDest));
 var ex = Expression.Lambda<Func<TItem, TDest>>(c, p).Compile();

 foreach (var item in items)
 {
    yield return ex(item);
 }
}

HTTP: //adventuresdotnet.blogspot كوم / 2010/06 / أفضل أكثر من نوع آمن بديل to.html

وشكرا لأنني كنت على وشك أن استخدام هذه الحالة بالضبط في مكان ما. لقد وفرت لي كومة من الزمن. كحل ممكن للمشكلة هل يمكن استخدام ConvertAll <> بدلا من ذلك، كما يلي:

foreach (Class1 item in items.ConvertAll<Class1>((i) => (Class1)i))
{
     Console.WriteLine(item.Test1);
}

وتحرير: أو إذا كنت تريد أن تكون أكثر وضوحا أن يلقي ضمني ثم يعمل هذا أيضا:

foreach (Class1 item in items.ConvertAll<Class1>(i => i))
{
     Console.WriteLine(item.Test1);
}

والحل يمكن أن يكون لاستخدام قليلا من linq'ing هنا إذا كنت حقا بحاجة الى هذا النوع من التحويل:

List items = new List{new Class2{Test2 = 9}};
foreach (Class1 item in (from x in items select (Class1)x))
{
    Console.WriteLine(item.Test1);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top