簡體   English   中英

C#反思:從程序集創建對象而無需調用ConstructorInfo

[英]C# Reflection: Create object from assembly without invoking constructorinfo

我在用反射調用構造函數時遇到問題。 無參數的構造函數沒問題,但是當我嘗試調用具有參數的一次時,我得到了missingMethodException

碼:

 if (type != null)
        {
            var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
               return Activator.CreateInstance(type);

            constructor = type.GetConstructors()[0];

            var parameters = constructor.GetParameters();

            var obj = new object[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

無參數構造函數可以正常工作。

 var constructor = type.GetConstructor(Type.EmptyTypes);
            if (constructor != null)
            {
                return Activator.CreateInstance(type);
            }

這部分不:

   constructor = type.GetConstructors()[0];

            var parameters = constructor.GetParameters();

            var obj = new object[parameters.Length];

            for (var i = 0; i < parameters.Length; i++)
            {
                obj[i] = (object) parameters[i].ParameterType;
            }
            return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, null);
        }

我知道其中一個構造函數如下所示:

 public class YYY: XXX
{
    public YYY(Guid customerId)
        : base(404, Level.Warn, null, string.Format("{0}",customerId))
    {
    }
}

我也知道parameterType不是構造函數想要的數據類型:

parameters[i].ParameterType is Guid
false

並且..我知道,如果我刪除obj並放入新的Guid()它將起作用:

return Activator.CreateInstance(type, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Guid(), null);

問題: 如何調用構造函數?

從以下方面找到了一些線索:

如何在C#方法中識別每種參數類型?

其中@JaredPar表示以下內容:要獲取參數的實際類型,請使用ParameterInfo值上的ParameterType。 使用該值,您可以通過多種方式使用它來標識類型。 最簡單的是直接與已知類型進行比較。

因此,在我的情況下,我需要先確定parameterType的類型並創建該類型的新實例,然后再將其發送給構造函數。

因為我只關心對象的類型,所以可以通過以下方式解決它:

var fixture = new Fixture(); //Ploeh.AutoFixture
var obj = new SpecimenContext(fixture).Resolve(asmtype); //Ploeh.AutoFixture.Kernel.SpecimenContext 

因此,在獲得AssemblyType之后,我只需創建一個Fixture和一個帶有Fixture的sampletContext,然后解析asmType。

該對象將是相應的類型。

所以最終結果:

   foreach (var asmtype in assemblyTypes)
        {
            var fixture = new Fixture();
            var obj = new SpecimenContext(fixture).Resolve(asmtype);

            _handler.Error(new Login { BrandId = _brandId }, new Domain.Entities.Customer { CustomerId = It.IsAny<Guid>() }, (Exception) obj);

            if (obj is InvalidCredentialsException)
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Once);
            else
                _loginRepository.Verify(v => v.ZZZ(It.IsAny<Guid>(), It.IsAny<int>()), Times.Never);
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM