غير قادر على تحويل كائن من النوع 'System.Object []' إلى 'MyObject []'، ما يعطي؟

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

سؤال

والسيناريو:

وأنا أكتب حاليا طبقة إلى مجردة 3 خدمات ويب مماثلة في الطبقة صالحة للاستعمال واحد. كل خدمة ويب يعرض مجموعة من الأشياء التي تشترك المشتركة. لقد خلق مجموعة من الكائنات الوسيطة التي تستغل المشتركة. ولكن في طبقة بلدي ولست بحاجة لتحويل بين كائنات خدمة الويب والكائنات الخاصة بي.

ولقد استعملت انعكاس لخلق نوع من المناسب في وقت التشغيل قبل أن إجراء المكالمة لخدمة الويب مثل ذلك:

    public static object[] CreateProperties(Type type, IProperty[] properties)
    {
        //Empty so return null
        if (properties==null || properties.Length == 0)
            return null;

        //Check the type is allowed
        CheckPropertyTypes("CreateProperties(Type,IProperty[])",type);

        //Convert the array of intermediary IProperty objects into
        // the passed service type e.g. Service1.Property
        object[] result = new object[properties.Length];
        for (int i = 0; i < properties.Length; i++)
        {
            IProperty fromProp = properties[i];
            object toProp = ReflectionUtility.CreateInstance(type, null);
            ServiceUtils.CopyProperties(fromProp, toProp);
            result[i] = toProp;
        }
        return result;
    }

إليك قانون بلدي الدعوة، من أحد تطبيقات خدمتي:

Property[] props = (Property[])ObjectFactory.CreateProperties(typeof(Property), properties);
_service.SetProperties(folderItem.Path, props);

وهكذا كل خدمة الكشف عن وجوه مختلفة "الملكية" التي اختبئ وراء تنفيذ بلدي بلدي اجهة IProperty.

والرمز انعكاس يعمل في وحدة الاختبارات إنتاج مجموعة من الكائنات عناصره هي من النوع المناسب. لكن رمز الدعوة فشل:

<اقتباس فقرة>   

وSystem.InvalidCastException: الإضافة غير قادر على   تحويل كائن من النوع 'System.Object []'   لكتابة   "MyProject.Property []

وأي أفكار؟

وكنت تحت انطباع بأن أي المدلى بها من كائن ستعمل طالما الكائن الواردة هو CONVERTABLE؟

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

المحلول

والجواب البديلة: الوراثة

public static T[] CreateProperties<T>(IProperty[] properties)
    where T : class, new()
{
    //Empty so return null
    if (properties==null || properties.Length == 0)
        return null;

    //Check the type is allowed
    CheckPropertyTypes("CreateProperties(Type,IProperty[])",typeof(T));

    //Convert the array of intermediary IProperty objects into
    // the passed service type e.g. Service1.Property
    T[] result = new T[properties.Length];
    for (int i = 0; i < properties.Length; i++)
    {
        T[i] = new T();
        ServiceUtils.CopyProperties(properties[i], t[i]);
    }
    return result;
}

وبعد ذلك يصبح كود دعوتكم:

Property[] props = ObjectFactory.CreateProperties<Property>(properties);
_service.SetProperties(folderItem.Path, props);

وأنظف بكثير:)

نصائح أخرى

وأساسا، لا. وهناك عدد قليل، محدودة، استخدامات التغاير مجموعة، ولكن من الأفضل أن مجرد معرفة أي نوع من المصفوفة التي تريد. هناك Array.ConvertAll عام أن من السهل بما فيه الكفاية (على الأقل، هو أسهل مع C # 3.0):

Property[] props = Array.ConvertAll(source, prop => (Property)prop);

والنسخة C # 2.0 (متطابقة في المعنى) هو أقل من ذلك بكثير صديقة للمقلة العين:

 Property[] props = Array.ConvertAll<object,Property>(
     source, delegate(object prop) { return (Property)prop; });

وأو مجرد إنشاء خاصية جديدة [] من الحجم الصحيح ونسخ يدويا (أو عن طريق Array.Copy).

وكمثال على ذلك من الأشياء التي يمكن علاقة مع التغاير مجموعة:

Property[] props = new Property[2];
props[0] = new Property();
props[1] = new Property();

object[] asObj = (object[])props;

وهنا، "asObj" هو لا تزال وProperty[] - انها مجرد الوصول إليها كما object[]. في C # 2.0 فما فوق، الأدوية عادة ما جعل خيار أفضل من التغاير مجموعة.

وكما قال آخرون، ومجموعة يجب أن تكون من النوع المناسب لتبدأ. أظهرت إجابات أخرى كيفية تحويل كائن حقيقي [] بعد وقوعها، ولكن هل يمكن أن تخلق الحق في نوع من مجموعة لتبدأ باستخدام <لأ href = "http://msdn.microsoft.com/en-us/library /system.array.createinstance.aspx "يختلط =" noreferrer "> Array.CreateInstance :

object[] result = (object[]) Array.CreateInstance(type, properties.Length);

وعلى افتراض type هو نوع مرجع، وهذا يجب أن تعمل - فإن مجموعة يكون من النوع الصحيح، ولكن عليك استخدامها بوصفها object[] فقط لملء ذلك

.

ولا يمكنك تحويل مجموعة من هذا القبيل - انها تعود لمجموعة من الكائنات، والتي تختلف من كائن. محاولة Array.ConvertAll

وهذا صحيح، ولكن هذا لا يعني أنك يمكن أن يلقي حاويات من نوع الكائن إلى حاويات من أنواع أخرى. كائن [] ليست نفس الشيء كائن (على الرغم من، الغريب، يمكن أن يلقي كائن [] لكائن).

وفي C # 2.0 لك <م> يمكن قيام بذلك التفكير به، دون استخدام الأدوية ودون معرفة النوع المطلوب في وقت الترجمة.

//get the data from the object factory
object[] newDataArray = AppObjectFactory.BuildInstances(Type.GetType("OutputData"));
if (newDataArray != null)
{
    SomeComplexObject result = new SomeComplexObject();
    //find the source
    Type resultTypeRef = result.GetType();
    //get a reference to the property
    PropertyInfo pi = resultTypeRef.GetProperty("TargetPropertyName");
    if (pi != null)
    {
        //create an array of the correct type with the correct number of items
        pi.SetValue(result, Array.CreateInstance(Type.GetType("OutputData"), newDataArray.Length), null);
        //copy the data and leverage Array.Copy's built in type casting
        Array.Copy(newDataArray, pi.GetValue(result, null) as Array, newDataArray.Length);
    }
}

وأنت تريد أن تحل محل كل Type.GetType ( "OutputData") يدعو وGetProperty ( "PROPERTYNAME") مع بعض التعليمات البرمجية التي يقرأ من ملف التكوين.

وأود أيضا أن استخدام عام لإملاء إنشاء SomeComplexObject

T result = new T();
Type resultTypeRef = result.GetType();

ولكن قلت لك لا تحتاج إلى استخدام الأدوية.

ولا ضمانات على الأداء / الكفاءة، ولكنه عمل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top