Тип передачи динамично к <T>

Python 2.6 или 3.0:

def bitsoncount(x):
    return bin(x).count('1')

Пример:

>>> x = 123
>>> bin(x)
'0b1111011'
>>> bitsoncount(x) 
6

Или

ответ Matt Howells в Python:

def bitsoncount(i):
    assert 0 <= i < 0x100000000
    i = i - ((i >> 1) & 0x55555555)
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
    return (((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) & 0xffffffff) >> 24

8
задан Marc Gravell 18 August 2009 в 08:33
поделиться

5 ответов

Это проблема, которую вы, вероятно, захотите избежать решения . возможно, посредством отражения, вызывать методы динамически без их статического разрешения, но это как бы нарушает всю суть аннотаций типов.

Либо сделайте следующее:

public string GetXML(IEnumerable listdata) {  
    foreach(object obj in listdata)   
        //logic to create xml  
}

... который теперь вы можете вызвать любой IEnumerable или записать его «современным» способом как:

public string GetXML(IEnumerable<object> listdata) {  
    foreach(object obj in listdata)   
        //logic to create xml  
}

... который вы можете вызвать с любым IEnumerable через GetXML (someEnumerable .Cast ()) , а в C # 4.0 даже напрямую путем ковариации.

Если вам нужен тип среды выполнения элемента, вы можете получить его, используя .GetType () для каждого элемент, или вы можете просто передать его в качестве параметра (и предоставить переопределение для обратной совместимости):

public string GetXML(Type elementType, IEnumerable<object> listdata) {  
    foreach(object obj in listdata)   
        //logic to create xml  
}

public string GetXML<T>(IEnumerable<T> listdata) {
    return GetXML(typeof(T),listdata.Cast<object>());
}

Между прочим, если вы создаете XML,

2
ответ дан 5 December 2019 в 08:54
поделиться

Поскольку вы передаете свой параметр listdata как List в первой строке вашего метода, почему бы вам просто не изменить подпись метода на

public string GetXML<T>(List<T> listdata)

Таким образом, вы не Чтобы получить общие аргументы, необходимо использовать отражение.

РЕДАКТИРОВАТЬ: Я вижу, что вам нужно иметь возможность принимать коллекции IEnumerable, а не только списки. Итак, рассмотрите возможность изменения сигнатуры вашего метода на

public string GetXML<T>(IEnumerable<T> listdata)
7
ответ дан 5 December 2019 в 08:54
поделиться

Для этого вам нужно использовать отражение;

typeof(SomeClass).GetMethod("GetXML").MakeGenericMethod(genericType)
         .Invoke(inst, new object[] {myRoleData});

где inst равно null , если это статический метод, this для текущего экземпляра (в этом случае вы также можете использовать GetType () вместо typeof (SomeClass) ) или целевой объект в противном случае.

8
ответ дан 5 December 2019 в 08:54
поделиться

У вас правильная идея, но вы используете неправильный метод. Посмотрите Type.MakeGenericType или MethodInfo.MakeGenericMethod. Это займет на несколько строк больше, чем ваш пример, но решить его должно быть просто.

GetGenericArguments () может использоваться для получения типа ролей из списка. Это другой способ.

Кстати: Похоже, вы реализуете какую-то сериализацию XML. Убедитесь, что вы проверили существующие классы, прежде чем изобретать колесо. ; -)

0
ответ дан 5 December 2019 в 08:54
поделиться

Я не знаю вашей ситуации, но можно ли переписать вашу функцию как:

public string GetXML<T>(IEnumerable<T> listdata)  
{  
    foreach(var obj in listdata)   
    {  
        //logic to create xml  
    }  
}

Тогда ее можно будет вызвать как:

List<Role> myList;
GetXML(myList);

Вы можете добавить параметры типа еще до необходимо поддерживать его, пока вы не доберетесь до места, где действительно известно, что такое твердый тип.

2
ответ дан 5 December 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: