简体   繁体   English

访问通过反射创建的类型的属性

[英]Access properties of a type created by reflection

I have the following code: 我有以下代码:

List<MultiServiceRequestMember> _memberList = new List<MultiServiceRequestMember>();
var type = Type.GetType(svc.NotificationClassName); <- this is a string of the class name.
MultiServiceRequestMember newMember = (MultiServiceRequestMember)Activator.CreateInstance(type);

_memberList.add(newMember);

The MultServiceRequestMember is a base type and I want to assign values to properties specific to type . MultServiceRequestMember是基本类型,我想将值分配给特定于type属性。 My question is: How do I cast newMember to type and access its properties? 我的问题是:如何转换newMember来键入和访问其属性?

How do I cast newMember to type and access it's properties? 如何转换newMember来键入和访问它的属性?

You can't cast it, because you don't know the specific type at compile-time. 你可以不 ,因为你不知道在编译时的特定类型。 If you did, you wouldn't need reflection in the first place! 如果您这样做了,那么首先就不需要反思!

You'll have to set the properties by reflection too: 您还必须通过反射来设置属性:

// TODO: Checking that you managed to get the property, that's it's writable etc.
var property = type.GetProperty("PropertyName");
property.SetValue(newMember, "new value", null);

You will have to change the code to look like this: 您将不得不将代码更改为如下所示:

List<MultiServiceRequestMember> _memberList = new List<MultiServiceRequestMember>();
var type = Type.GetType(svc.NotificationClassName);
MultiServiceRequestMember newMember = null;
if (type == typeof(MultiServiceRequestMemberA))
{
    newMember = new MultiServiceRequestMemberA();
    //set specific properties
}
else if (type == typeof(MultiServiceRequestMemberB)) //etc.
{
    //...
}
else
{
    //throw or some default
}

_memberList.add(newMember);

However, it looks like code smell. 但是,它看起来像代码气味。 I guess you're trying to initialize an object based on some other object (let's call it NotificationInfo). 我猜您正在尝试基于其他对象初始化一个对象(我们将其称为NotificationInfo)。 Then instead of code that looks like this: 然后,而不是看起来像这样的代码:

if (type == typeof(MultiServiceRequestMemberA))
{
    newMember = new MultiServiceRequestMemberA();
    newMember.A = notificationInfo.A;
}

Maybe should think of following design: 也许应该考虑以下设计:

class MultiServiceRequestMember
{
    public virtual void Initialize(NotificationInfo notificationInfo) //or abstract if you wish
    {
    }
}

class MultiServiceRequestMemberA : MultiServiceRequestMember
{
    public override void Initialize(NotificationInfo notificationInfo)
    {
        base.Initialize(notificationInfo);
        this.A = notificationInfo.A;
    }
}

And then you will be able to leave your previous code and just call Initialize. 然后,您将可以保留先前的代码,而只需调用Initialize。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM