C#带有条件语句的通用类型参数

5

我正在使用 C# API,有以下几个类。其中有两个消息类MessageAMessageB,以及一些字段类FieldAFieldB等。所有字段类都属于基类Field

一个消息将包含各种字段,可以通过以下方式访问:

msgA.getField(FieldX field)

(将msgA中的FieldX条目(如果存在)复制到field),以及

msgB.set(FieldX field).

还有

msgA.isSetField(FieldX field)

确保消息包含类型为FieldX的字段。

我需要编写一个方法,将MessageA中的某些字段复制到MessageB中。我现在有一个可用的函数,但它有很多类似下面这样的语句。

FieldX fieldX = new FieldX();
if(msgA.isSetField(fieldX))
{
    msgA.getField(fieldX);
    msgB.set(fieldX);
}

对我来说,这似乎有点愚蠢,因此我想编写一个单独的方法来完成这个任务。然而,我对C#和泛型类型还很陌生,所以我不太确定最佳的方法是什么。在尝试了许多方法后,我写了以下代码:

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);
        }
    }
}

但这并不起作用。在内部条件语句中,field_t的类型被转换为int。这种情况有点合理,因为这些函数不能将任何类型作为参数,所以编译器无法确定每次都能正常工作。但我想知道是否有人可以指出一个解决问题的好方法。欢迎向我链接MSDN文章、教程或其他资料。感谢您的任何帮助。

你尝试过在方法签名中使用T field而不是Field field吗?这样可以减少强制类型转换的需要。 - drharris
好的,这确实简化了它,但问题仍然存在。谢谢。 - Kris Harper
1个回答

3

只有当您的消息对象方法也是通用的时,才有意义在此处使用泛型:

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 { ... }
}

那么你的方法就可以真正地通用:
private void SetMessageB<T>(Message msgA, Message msgB, T field) where T : Field
{
    if (msgA.isSetField(field))
    {
      msgA.getField(field);
      msgB.set(field);
    }
}

啊,这很有道理。你有任何想法如何实现这个吗?我也考虑过创建一个List<Field>,添加一堆新的FieldX到其中,但是我遇到了类似的问题。 - Kris Harper
你需要提供更多关于你想要实现的具体细节。对于混合字段类型的列表,你仍然需要进行强制转换。 - Mark Cidade
我只是想稍微整理一下我的方法。现在我有大约20个这样的语句,所以我想肯定有一些方法可以使它不那么重复。但每次我尝试一些东西(例如传递到不同的方法或使用混合类型的列表),我都会遇到麻烦,因为这些字段都是不同的类型。我假设有一种结构可以让我只写一次这个设置,我只是不知道是什么。 - Kris Harper
你可能想要考虑使用像 Func<TField,TValue> 这样的委托,将它们作为lambda表达式(例如field => field.Value)传递给接受通用 Field 对象的方法,然后调用委托从字段获取特定于类型的值。如果只能在运行时了解类型(例如,使用混合列表),则必须使用反射或 dynamic - Mark Cidade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接