Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
274 views
in Technique[技术] by (71.8m points)

c# - Cast to generic where type is unknown

The following code is a simplified version what I have:

public class Message
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
}

public class ExtendedMessage<TExtension> : Message 
{
    public TExtension Extension { get; set; }
}

public class Processor<T> where T : Message
{
    public void Process(T message)
    {

    }
}

I will have many types that inherit from either Message or ExtendedMessage. I would like to be able to use Processor to process those that inherit from ExtendedMessage<> as well as Message. However that involves manipulating the Extension property for those that have it.

In order to do that it seems I would need to cast the message parameter to the process method to ExtendedMessage<>, if it is of that type. I have tried to do that using the following:

if (IsInstanceOfGenericType(typeof(JsonModel<>), model))
{
    var dataType = message.GetType().GetGenericArguments()[0];
    Type type = typeof(ExtendedMessage<>).MakeGenericType(dataType);
    var extendedMsg = Activator.CreateInstance(type);
    //Processing using extendedMsg.Extension
}

Where IsInstanceOfGenericType is from this answer: Testing if object is of generic type in C#

However that does not work, obviously the property is not available. Is it possible to process both types in the same method? Am I going about this the right way in the first place? I would like to avoid extending Processor to create a separate ExtendedMessageProcessor if possible. Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The easy-but-wrong answer would be to use dynamics:

var extension = ((dynamic)message).Extension

A better answer would be to have your extensions inherit from a base

public class ExtendedMessage : Message 
{
    public ExtensionBase Extension { get; set; }
}

public abstract class ExtensionBase
{

}

...

var extendedMessage = message as ExtendedMessage;
if (extendedMessage != null)
{
    //process
}

If something like this isn't possible and you're stuck with reflection, you don't want to create a new instance of the message. You already have the message and it has the properties on it you need. You should be using Type.GetProperties() and Type.GetMethods().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...