MyDaftQuestions
MyDaftQuestions

Reputation: 4701

Cannot cast object of T to concrete type

I'm trying to understand generic types. However, I think I'm getting confused with fakes.

On my system, I'd like to load something. It doesn't matter what it is, and it could be anything. The caller will konw what it is.

My approach is to use an interface, where the interface is simply

public interface ILoad
{
    void Load<T>(T t);  
}

In my Bll class, I have a method which is

public void Start(ILoad load)
{
    load.Load<Survey>(this);     // I'm telling it the type and passing it the object
}

public class FakeLoadForSurvey : ILoad     //this class knows about Survey 
{
    public void Load<T>(T t)
    {
         t = new Survey();            //fails
    {
}

It fails with the following error message

Cannot implicity convert type Survey to T

I hope the above example is clear enough.

How do I tell C# that T is of type Survey (or any other type)?

Upvotes: 0

Views: 154

Answers (3)

bommelding
bommelding

Reputation: 3037

public void Load<T>(T t) where T: Survey, new()
{
     t = (T) new Survey();            // should succeed
}

But with a void return and without ref on the parameter this function still won't do anything useful.

Upvotes: -1

Patrick Hofman
Patrick Hofman

Reputation: 157126

This code looks bad from a design point of view, since you are mixing generics with statically defined types. If you use generics, you should go all the way:

public interface ILoad
{
    void Load<T>(T t) where T : new();  
}

public class FakeLoadForSurvey : ILoad
{
    public void Load<T>(T t) where T : new()
    {
         t = new T();
    }
}

I am not sure what your intention is with the parameter you define, but it loses scope after the method, so t will never of any use outside of the Load<T> method.

Upvotes: 2

CodeCaster
CodeCaster

Reputation: 151720

public class FakeLoadForSurvey : ILoad     //this class knows about Survey 

If the class implementing the interface knows the type for T, then move T to the interface:

public interface ILoad<T>
{
    void Load(T t);  
}

public class FakeLoadForSurvey : ILoad<Survey>
{
    public void Load(Survey t)
    {
         t = new Survey();
    }
}

Do note however that this won't affect the argument passed to Load().

So if some code calls it like this:

var surveyLoader = new FakeLoadForSurvey();
Survey surveyToLoad = null;

surveyLoader.Load(surveyLoader);

Then surveyToLoad is still null after Load() returns. If you don't want that, pass it with ref.

Upvotes: 7

Related Questions