Chris P. Bacon Chris P. Bacon - 1 month ago 6
C# Question

C# Passing a Generic Class As a Method Parameter

I have a

CreateMessage class
that is meant to handle incoming messages from a
TCPClient
, get the user type and return how the message should be formatted to its calling
method
.

In the method
GetUserType
, I want to pass
UserBaseType
as a parameter, which is a
generic abstract class
that takes a
Type
of
UserType
. However, it gives me the error:


Using the generic type 'UserTypeBase' requires one type argument.


I'm still trying to wrap my head around using generics and constraints, so I don't know if I'm going about this the wrong way. I've done a bit of digging to try to find a solution myself, but haven't found anything that more or less tailors to what I'm trying to do.

internal class CreateMessage
{
internal static string user;
internal static string message;

internal CreateMessage(string data)
{
user = Lists.users[data.Substring(1, 3)];
message = data.Substring(5, data.Length - 5);
}

private UserType GetUserType(UserTypeBase type)
{
return type.CreateType();
}

internal string Message()
{
UserType Type = null;
if (user.Contains("[M]"))
Type = GetUserType(UserMod);
else if (user.Contains("[B]"))
Type = GetUserType(UserVIP);
else
Type = GetUserType(UserRegular);
return Type.Message();
}
}


UserBaseType.cs

internal abstract class UserTypeBase<T> where T: UserType
{
public abstract string User { get; }
public abstract string Message { get; }
public abstract T CreateType();
}

Answer

You're going to want to make the method that takes the parameter generic as well. You're going to also want to mirror the type constraints as they appear on the parametric type to avoid compilation errors, as well as be explicit in what is and is not acceptable for the method.

private T GetUserType<T>(UserTypeBase<T> type) where T : UserType
{
    return type.CreateType();
}

You can then call it with the type provided explicitly or implicitly, depending on the situation.

var someType = new UserTypeDerived<UserType>();
var resultImplicit = GetUserType(someType);
var resultExplicit = GetUserType<UserType>(someType);

Since it's a parameter that is being used generically, the compiler can implicitly determine what the expected value of T is based on the type of the parameter supplied.