C# Generic Type Parameter with a Conditional Statement
I'm working with an API in C# with some classes as follows. There are two message classes MessageA
and MessageB
and a number of field classes FieldA
, FieldB
, etc. The field classes all belong to a base class Field
.
A message will contain various fields which can be accessed as
msgA.getField(FieldX field)
(copies the FieldX
entry (if it exists) from msgA
to field
) and
msgB.set(FieldX field)
.
There's also
msgA.isSetField(FieldX field)
to make sure a message contains a field of type FieldX
.
I need to write a method to take a MessageA
and copy over some of fields to a MessageB
. I have a working function now, but it has a whole bunch of statements like
FieldX fieldX = new FieldX();
if(msgA.isSetField(fieldX))
{
msgA.getField(fieldX);
msgB.set(fieldX);
}
This seems silly to me, so I'd like to write a separate method to do this. I'm new to C# and generic types though, so I'm not quite sure the best way to do it. After trying a number of things, I've written
private void SetMessageB<T>(MessageA msgA, MessageB msgB, Field field) where T : Field
{
var field_t = field as T;
if (field_t != null)
{
if (msgA.isSetField(开发者_如何转开发field_t))
{
msgA.getField(field_t);
msgB.set(field_t);
}
}
}
But this doesn't work. Within the inner conditional statement, the type of field_t
gets converted to int
. It sort of makes sense why this would happen (i.e., these functions can't take any type as an argument, so the compiler can't be sure it will work every time). But I'm wondering if someone can point out a good way to solve the problem. Feel free to link me to MSDN articles or tutorials or whatnot. Thanks for any help.
It would only make sense to use generics here if your message object's methods were generic as well:
class Message
{
bool isSetField<TField>(TField field) where TField : Field { ... }
void getField<TField>(TField field) where TField : Field { ... }
void set<TField>(TField field) where TField : Field { ... }
}
Then your method can be truly generic:
private void SetMessageB<T>(Message msgA, Message msgB, T field) where T : Field
{
if (msgA.isSetField(field))
{
msgA.getField(field);
msgB.set(field);
}
}
精彩评论