4

2 つのプロジェクトを含むプロジェクトを作成しました。1 つはコンソール アプリケーションで、もう 1 つはクラス ライブラリ プロジェクトです。

クラス ライブラリ プロジェクトからの dll 参照をコンソール アプリケーションに追加しました。

クラス ライブラリ プロジェクトからオブジェクトを返すと、コンソール アプリケーションで取得できますが、キャストしようとしても機能しません。

タイプaをタイプbに変換できないため、エラーがスローされます。

私は何時間もこのエラーに苦しんでいます。

クラス ライブラリ プロジェクトの私のコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary1
{
    public class Class1
    {
        public object dyn()
        {
            var obj = new { ID = 2, Name = "Rajesh" };
            return obj;
        }
    }
}

上記では、リストをオブジェクトとして返しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq;
using System.Data.SqlClient;
using System.Collections;
using System.Data;
using ClassLibrary1;
using System.Reflection;
using System.ComponentModel;
namespace ConsoleApplication2
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Program objPgm = new Program();
            Class1 objCls=new Class1();            
            object obj = objCls.dyn();
            var list = objPgm.cast(obj, new { ID = 0, Name = "" });
        }

        public  T cast<T>(object obj,T type) 
        {          
            return (T)obj; 
        }
}

上記のコードで、クラス ライブラリ プロジェクトからオブジェクトを取得し、キャストしようとすると InvalidCastException がスローされます。

これに対する修正はありますか。

この問題について私を助けてください。

前もって感謝します。

4

2 に答える 2

5

CastByExampleトリックを使用しているようです。コンパイラは各アセンブリで 2 つの独立した匿名型を生成するため、アセンブリからは機能しません。

最善の回避策は、独自の型を使用することです。共通アセンブリで共有する

public class MyData
{
   public int ID {get;set;}
   public string Name{get;set;}
}
于 2013-11-11T16:01:34.153 に答える
4

匿名型は、次の場合にのみ同じコンパイル時の型を共有します。

  • それらはまったく同じパラメーター名、タイプ、および順序を共有します
  • それらは同じアセンブリに存在します

またはMSDNから

アセンブリ内の2 つ以上の匿名オブジェクト初期化子が、同じ順序で同じ名前と型を持つ一連のプロパティを指定する場合、コンパイラはオブジェクトを同じ型のインスタンスとして扱います。

最初のものは持っていますが、2番目のものは持っていません。したがって、2 つの匿名型は同じように見えますが、C# とランタイムに関する限り、これらは 2 つの完全に異なる、互換性のない型です。

理想的には、匿名型は (現在わかっているように) 正確には使用できないため、メソッドから返されるべきではありません。

この場合、 と を含むクラスを単純に定義する方がはるかに優れていClassLibrary1ます。これにより、プロセス全体が厳密に型付けされ、返される情報の構造を本質的に複製する必要がなくなります。IDName


コードが(多かれ少なかれ)現在行っていることの例を示すには:

namespace ClassLibrary1
{
    internal class ClassLibrary1_AnonObj1
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class Class1
    {
        public object dyn()
        {
            var obj = new ClassLibrary1_AnonObj1 { ID = 2, Name = "Rajesh" };
            return obj;
        }
    }
}

namespace ConsoleApplication2
{
    internal class ClassLibrary2_AnonObj2
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Program objPgm = new Program();
            Class1 objCls=new Class1();            
            object obj = objCls.dyn();
            var list = objPgm.cast(obj, new ClassLibrary2_AnonObj2 { ID = 0, Name = "" });
        }

        public  T cast<T>(object obj,T type) 
        {          
            return (T)obj; 
        }
    }
}

これはキャストのようなものです:

ClassLibrary1_AnonObj1 obj = new ClassLibrary1_AnonObj1();
ClassLibrary2_AnonObj2 obj2 = (ClassLibrary2_AnonObj2)obj;

これが、2 つのタイプが完全に異なるように見えるため、失敗する理由です。代わりに、独自のクラスを宣言して使用する場合:

namespace ClassLibrary1
{
    public class MyInfo
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class Class1
    {
        public MyInfo dyn()
        {
            var obj = new MyInfo { ID = 2, Name = "Rajesh" };
            return obj;
        }
    }
}

namespace ConsoleApplication2
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Program objPgm = new Program();
            Class1 objCls=new Class1();            
            MyInfo obj = objCls.dyn();
        }
    }
}

これにより、キャストの必要がなくなります。または、それを返し続ける必要がある場合はobject、この時点で単純にキャストできます。

Class1 objCls=new Class1();            
MyInfo obj = (MyInfo)objCls.dyn();

の使用はdyn()、動的に作成されたコンテンツ、または異なるタイプを返すことを意図していると思われますが。おそらく、より多くのコンテキスト、リファクタリング、またはより良い設計が必要です。

于 2013-11-11T16:03:11.430 に答える