1

I have two class like this

public class excel: document{

}

public class pdf: document{

}

and a base class document.

I have an enum

public enum DocumentType{
    excel = 1,
    pdf = 2
}

I have a core class with a generic method implemented method

public class manager{

    LoadFile<T> (Stream stream) where T: document{
    ...
    }

}

Can i call the loadfile method with a command like this

Type GetType(DocumentType documentType){
    ...
}

LoadFile<GetType(DocumentType.excel)>(myStream){
    ...
}

I want have a generic parameter created by the enum.

the error is

< generic cannot be applied to operands of type 'method group'

user3401335
  • 2,335
  • 2
  • 19
  • 32
  • I don't think you know what generics are. You can't do this with out reflection or on the go compilation with expressions. – Filip Cordas Sep 11 '17 at 08:20
  • 1
    `LoadFile (Stream stream) where T: document{` is missing a return type, isn't it? – Fildor Sep 11 '17 at 08:21
  • 1
    This can be solved through reflection (use `GetMethod` for `LoadFile`), as given in similar issue there: https://social.msdn.microsoft.com/Forums/en-US/0eaa1ba9-2167-4776-857c-39d06cc8708c/error-1-operator-cannot-be-applied-to-operands-of-type-method-group-and-systemtype?forum=csharplanguage. – Tetsuya Yamamoto Sep 11 '17 at 08:22
  • When generics are *consumed*, the type parameters have to be known at *compile time* for the consuming code. – Damien_The_Unbeliever Sep 11 '17 at 08:22

1 Answers1

0

For cases where you know the type at compile time, such as "please load this pdf, it's definitely going to be a pdf" - then I don't see any reason to look at generics at all. You're not saving yourself any time over just instantiating the object with the stream data, and letting it build itself.

// for example
class pdf : document {
    public pdf(Stream stream)
    {
         // load the pdf data from the stream here
    }
}

For cases where you don't know the object type, "load the file the user selected, it might be a pdf, it might be an excel file", you also don't want to be worrying about generics. Instead, you want a function that returns a base document type - as you don't know what type it is before loading (i.e. at compile time, you don't know - so you can't use generics):

document LoadFromStream(Stream stream)
{
    var typeOfDocument = SomeMethodToFindTheFileTypeFromTheStream(stream);
    switch(typeOfDocument)
    {
        case DocumentType.pdf:
            return LoadPDFFromStream(stream);  // returns pdf object
        case DocumentType.excel:
            return LoadExcelFromStream(stream);  // returns an excel object
        default:
            throw new Exception("Document is not a supported type");
    }
}

If you then need the specific object, you'll need to downcast it using information within the object (such as a document type enum) to figure out which type to cast it to.

There is no silver-bullet generic solution to this I'm afraid. If you know the file type at compile time, generics aren't saving you anything. If you don't - you need some conditional logic to determine what type it actually is (whether this is before or after loading, e.g. using the file extension to decide).

Generics won't save you time or make your life easier here at all.