Click here to Skip to main content
15,887,776 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
C# Generics question,

I'm getting the following error on the caller side:

The type arguments for method 'xxxxxxxx' cannot be inferred from the usage. Try specifying the type arguments explicitly.

The caller:

List<TransferObject> lstTransferObject = new List<TransferObject>();

lstTransferObject = GetDtoList(a, b);


The error is on the GetDtoList method, I've tried specifying the call as .GetDtoList((string) a, (byte[]) b) and this didn't work, so I'm misinterpreting the error message. The source for GetDtoList is as follows:

public static List<T> GetDtoList<T>(string k, byte[] s)
{
    List<T> lst = new List<T>();
    foreach(Code_dto dto in Code_GetList())
    {
        dynamic item = new { Name = "code", Data = dto.GetCodeString(k, s) };
        lst.Add(item);
    }

    return lst;
}



In response to question below... nothing exciting, it just returns a list. Looks something like this:
private static List<Code_dto> Code_GetList()
{
	List<Code_dto> lstCodeDto = new List<Code_dto>();
	
	// Grab records from the db and add to the list
	
	return lstCodeDto;
}


What I have tried:

1) Ran issue by other teammate
2) Researched similar stack & CP issues (most seem to be MVC based).
Posted
Updated 19-Sep-16 11:00am
v6
Comments
David_Wimbley 19-Sep-16 15:17pm    
Can you provide the code for Code_GetList(). The idea being here you want to provide all the code you can for someone to replicate your issue to provide you the best help possible. At the moment, I don't see how anyone can help as we don't know what Code_GetList() does/is.
[no name] 19-Sep-16 15:27pm    
What are "a" and "b"? How many GetDtoList methods do you have?
littleGreenDude 19-Sep-16 15:52pm    
Just the one GetDtoList
[no name] 19-Sep-16 16:08pm    
Well since you haven't provided a SCCE that demonstrates the problem, my guess would be that the list returned by Code_GetList does not contain the expected data type of TransferObject. Unless you have some hidden code somewhere that converts Code_dtos to TransferObjects....
littleGreenDude 19-Sep-16 16:03pm    
a is a string and b is a byte array

1 solution

The type argument for a generic type parameter can only be inferred if it is used in an input parameter. In all other cases, the type parameter must be declared explicitly.

The type parameter can be inferred for all of these:
C#
public static T Foo<T>(T bar) { ... }
int x = Foo(42);

public static T FirstOrDefault<T>(IEnumerable<T> source) { ... }
string item = FirstOrDefault(myListOfStrings);

public static IEnumerable<T> Where<T>(IEnumerable<T> source, Func<T, bool> predicate) { ... }
IEnumerable<Bar> filteredList = Where(myListOfBars, bar => someCondition);


But when none of the input parameters are related to the type parameter, you have to specify the type parameter explicitly:
C#
public static List<T> MakeAList<T>(int x, string y) { ... }

List<Bar> myList = MakeAList(42, "Hello"); // Compiler error
List<Bar> myList = MakeAList<Bar>(42, "Hello"); // OK


So, in your example, you need:
C#
lstTransferObject = GetDtoList<TransferObject>(a, b);


HOWEVER, this will not work. Your code will compile, but you will get an exception at runtime, because you're trying to add an object of one type to a list of a different type. If you replace the dynamic keywork with either object or T, you'll get a compiler error which shows you what the problem is.

If you want to return a list of dynamic objects, then your method should return List<dynamic>. If you want to return a list of a specific type, then you need to create an instance of that specific type in your loop.
 
Share this answer
 
Comments
Maciej Los 19-Sep-16 17:04pm    
Sounds very reasonable, a5!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900