1

ユーザーインターフェイスから取得する文字列に基づいてクラスのインスタンスを作成しようとしています。次に、クラスのインスタンスのプロパティにアクセスしたいと思います。

これが私がこれまでに持っているものの概要です-

namespace MamdaAdapter
{
    public interface IExchange
    {
        string GetTransport();
    }
}


namespace MamdaAdapter
{
    public class Exchange
    {
        public class Arca : IExchange
        {
            private const string _Transport = "tportname";

            public string GetTransport()
            {
                return _Transport;
            }
        }


        public static IExchange DeriveExchange(string ExchangeName)
        {
            IExchange SelectedExchange = (IExchange)Activator.CreateInstance(Type.GetType(ExchangeName));

            return SelectedExchange;
        }
    }
}



namespace MyUserInterface
{
    public class MainForm
    {
        private void simpleButton1_Click(object sender, EventArgs e)
        {
            IExchange SelectedExchange = Exchange.DeriveExchange("Exchange.Arca");

            Console.WriteLine(SelectedExchange.GetTransport());
        }
    }
}

更新: 現在、「値をnullにすることはできません」という例外が発生しています。これは、指定された文字列を指定すると、クラスのインスタンスを作成できないことを意味します-

4

4 に答える 4

2

UIが完全な型名を公開しないと仮定すると、通常、辞書で表示名を型に関連付ける必要があります。

Dictionary<string, Type> _associations = new Dictionary<string, Type>(); 

次に、新しいオブジェクトをインスタンス化するだけです。

if(_associations.ContainsKey(someString))
{
   Type selectedType = _associations[someString];

   return Activator.CreateInstance(selectedType) as IExchange;
}

throw new ApplicationException("No type defined for that string yo");

コンパイル時に文字列がわからない場合は、基本的に次のタイプの存在を確認する必要があります。

var type = Type.GetType(someString);

if(type != null)
{
    // Do Stuff
}
于 2011-08-25T18:27:59.320 に答える
2

ここでの問題は、クラスの名前をどのように指定するかです。

まず、名前空間を指定します。次に、Arcaは内部クラスであるため、「。」の代わりに「+」を使用する必要があります。

(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
于 2011-08-25T21:42:36.320 に答える
0

私はあなたのニーズをシミュレートするために小さなc#コンソールアプリケーションを作成し、テストしました。それが役立つことを願っています:

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IExchange SelectedExchange = Exchange.DeriveExchange("MamdaAdapter.Arca");
            Console.WriteLine(SelectedExchange.GetTransport());
        }
    }
}

namespace MamdaAdapter
{
    public interface IExchange
    {
        string GetTransport();
    }
}


namespace MamdaAdapter
{
    public class Arca : IExchange
    {
        private const string _Transport = "tportname";

        public string GetTransport()
        {
            return _Transport;
        }
    }
}

namespace MamdaAdapter
{
    public class Exchange
    {
        public static IExchange DeriveExchange(string ExchangeName)
        {
            IExchange SelectedExchange = (IExchange)Assembly.GetAssembly(typeof(IExchange)).CreateInstance(ExchangeName, false, BindingFlags.CreateInstance, null, null, null, null);
            return SelectedExchange;
        }
    }

}
于 2011-08-25T19:04:31.343 に答える
0

探しているタイプがType.GetTypeを実行しているのと同じアセンブリで定義されていない場合は、AssemblyQualifiedName(MyNamespace.MyClass、MyAssembly、Version = 1.3.0.0、Culture = neutral、PublicKeyToken = b17a5c561934e089など)を使用する必要があります。 FullNameでは不十分です。それ以外の場合は、最初にクラスを含むアセンブリを取得してから、AssemblyクラスのGetTypeメソッドを実行できます。

于 2011-08-25T21:39:40.640 に答える