简体   繁体   中英

How to pass params object[i] to a template function in C#

I am trying to send a params object[i] to a T function but I cant find the right syntax.

Here is an example to show the context of what I am trying to achieve:

private bool decodeValue<T>(int id,ref T item, string code)
{

    if(!TypeDescriptor.GetConverter (item).CanConvertFrom(typeof(string)))
    {
        errorThrow (id + 2);
        return false;
    }

    try
    {
        item = ((T)TypeDescriptor.GetConverter (item).ConvertFromString (code));
    }
    catch 
    {
        errorThrow (id + 2);
        //item = default(T);
        return false;
    }

    return true;
}

private bool decodeValues(string[] code, int id, params object[] items)
{
    for (int i = 0; i < items.Length; i++) 
    {
        System.Type t = items [i].GetType(); 
        //in this part i cant find the correct syntax
        if(decodeValue<(t)items[i]>(id, ref items[i] as t, code[i+2]))
        {

        }
    }

    return false;
}

At the line decodeValue<(t)items[i]>(id, ref items[i] as t, code[i+2] no matter what syntax I try, the compiler tells me that after > it expects a )

I could inline the function decodeValue into the for loop but I think there is a more elegant way of doing it. Any suggestions?

In your example, you replace content of items. Why do even need templated function? Just do this:

private bool decodeValue(int id,ref object item, string code)
{

    if(!TypeDescriptor.GetConverter(item).CanConvertFrom(typeof(string)))
    {
        errorThrow (id + 2);
        return false;
    }
    try
    {
        item = TypeDescriptor.GetConverter(item).ConvertFromString(code);
    }
    catch 
    {
        errorThrow (id + 2);
        return false;
    }

    return true;
}

private bool decodeValues(string[] code, int id, params object[] items)
{
    for (int i = 0; i < items.Length; i++) 
    {
        //in this part i cant find the correct syntax
        if(decodeValue(id, ref items[i], code[i+2]))
        {

        }
    }

    return false;
}

If you ever need type of item in your code, just call .GetType() where it actualy needed. That is not only good way to do things, but in some cases performance effective (compiler can greatly optimise some calls of this function).

generics ( <T> ) and reflection ( .GetType() ) are not good friends. There is no convenient way to express that. You can , however, abuse dynamic to do it, but you can't easily use ref in that case. Further, you can't ref between an object and a T . So basically, there's a lot of hurdles. Frankly, I think you should assess whether decodeValue<T> really needs to be generic. In this scenario - especially when using TypeDescriptor - I very much doubt that it needs to be. I suspect your best bet would be to have:

private bool DecodeValue(int id, ref object item, Type type, string code)

The generics' syntax if for compile time while GetType() is for runtime. You cannot mix them of use them together.

A generic class is resolved while you source is converted to binary. The type or interface provided in a generic type is used in that area.

On the contrary GetType returns a type during execution. That type cannot be inserted in a generic definition because compilation has already be done at that time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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