5

I am working with someone else's code and trying to make some modifications. So what I'm needing to do is take the following:

RemoteFileDP remoteFile = new DPFactory().CreateRemoteFileDP(configData);

And change it so that remoteFile can equal what is in a string variable. To further explain let me give some more of the code:

ConfigDP configData = new ConfigDP();

So the statement above is executed before the remoteFile statement and ConfigDP is has two classes above it (abstract Config and then its base: abstract ConfigBase). DP is also the child of two abstract classes above it (abstract RemoteFile and abstract RemoteFileBase).

From my understanding remoteFile is the result of data extracted from a database query, stored into a list or a Hashtable (sorry just an intern so I'm working through this).

The reason I need remoteFile to accept a string value is because there are MANY methods that utilize the information in remoteFile and I would like to avoid having to create a WHOLE BUNCH of overloaded methods that accept a string value instead of RemoteFileDP remoteFile.

So if I can take a string value like:

string locationDirectory;

which is passed in from another method and then have something similar to the following:

RemoteFileDP remoteFile = locationDirectory;

then all other methods using remoteFile will not have to be overloaded or changed.

Sorry for all the detail but this is my first time posting so I hope I provided enough information. I did look at C# Convert dynamic string to existing Class and C#: Instantiate an object with a runtime-determined type and wrote the following code:

RemoteFilesDP remoteFile = (RemoteFileDP)Activator.CreateInstance(typeof(RemoteFileDP), locationDirectory);

However I keep getting a "MissingMethodException" error that the constructor for RemoteFileDP is not found but I do have the constructor as seen below:

public RemoteFileDP()
    {
    } //end of RemoteFilePlattsDP constructor

Thank you ahead of time for your assistance!

Community
  • 1
  • 1
Invaderleige
  • 53
  • 1
  • 5
  • maybe this can help? http://stackoverflow.com/questions/208777/activator-createinstance-cant-find-the-constructor-missingmethodexception have you tried these? – Can Poyrazoğlu Jul 07 '11 at 23:01
  • Thank you for the reply. I will look at them right now! – Invaderleige Jul 07 '11 at 23:19
  • After pulling up the link I saw that this is one that I had been reviewing after I posted my question. I tried [FormatterServices.GetUninitializedObject](http://stackoverflow.com/questions/178645/how-does-wcf-deserialization-instantiate-objects-without-calling-a-constructor#179486/) but it did not work for me. Said that there was not an overload that accepted two arguments. – Invaderleige Jul 07 '11 at 23:22
  • Weird, where does it say that? Compiler error, runtime error? Where exactly? – Can Poyrazoğlu Jul 08 '11 at 00:11
  • @ can poyrazoğlu: It gives the error at compile time. This is the code I used: 'RemoteFileDP remoteFile = (RemoteFileDP)FormatterServices.GetUninitializedObject(typeof(RemoteFileDP), locationDirectory);' – Invaderleige Jul 08 '11 at 13:32
  • It's true, GetUninitializedObject does not take two arguments, and you called it with a Type and locationDirectory, which is wrong. – Can Poyrazoğlu Jul 08 '11 at 15:10

3 Answers3

2

If you don't wish to modify the source project that RemoteFileDP lives in (or can't) you could write an extension method such as below:

public static RemoteFileDP ConvertToRemoteFileDP(this string location)
{
    // Somehow create a RemoteFileDP object with your 
    // location string and return it
}

That way you could run the line of code you want:

RemoteFileDP remoteFile = locationDirectory;

With a slight modification as follows:

RemoteFileDP remoteFile = locationDirectory.ConvertToRemoteFileDP();

Would this allow you to solve your problem?

Thebigcheeze
  • 3,408
  • 2
  • 22
  • 18
  • Hmmm...I will have to try this. It might take some work because RemoteFileDP is a child of some abstract classess so I have to make sure all those abstract classes have this same abstract method but I will try it and let you know. – Invaderleige Jul 07 '11 at 23:26
  • +1. This is the best way since you cannot make a string implicitly convertible to a class, and also cannot overload the = operator. – Ed Bayiates Jul 07 '11 at 23:28
  • So I'm working on this now but being I'm still a novice I will have to figure out how to make the part in your code comments happen. Create a RemoteFileDP object with the location string. But I will let you know when it is done – Invaderleige Jul 07 '11 at 23:32
  • As a general rule, try looking around other places that build the `RemoteFileDP` object from some sort of user or file input, and then follow patterns they've used there. – Thebigcheeze Jul 07 '11 at 23:47
  • So I finished working on the code from the suggestion that "Anna Lear" provided and it worked. Sorry I approached her's first, it was just easier to figure out. However I like to learn different ways to doing things and don't always want to take the easy method. So I'm still working on yours and will let you know. – Invaderleige Jul 07 '11 at 23:55
  • Well I've been working on this code and have several errors. Things like: "Extension must be defined in a non-generic static class" for the RemoteFileDP and its parent class. Then I also get: " 'string' does not contain a definition for ConvertToRemoteFileDP and no extension method ConvertToRemoteFileDP accepting a first argument of type 'string' could be found (are you missing using directive or an assembly reference? " Yet I wrote it as you stated: RemoteFileDP remoteFile = new RemoteFileDP(locationDirectory); So I will have to focus on this tomorrow. – Invaderleige Jul 08 '11 at 00:34
  • @Thebigcheeze and @AresAvatar: So it seems that I need to go change all parent classes to static classes because of the "non-generic" error I mentioned above. This would impact several other aspects to the program that I don't believe they are wanting me to rewrite entirely. I still can't figure out why the second error is happing at compile time. I do appreciate all your help and if I wasn't so restricted with the changes made to the program then maybe I could get this to work. Thanks again! – Invaderleige Jul 08 '11 at 13:18
  • As a note about extension methods in general: Extension methods must exist in any public static class that your code can see, and must be a public static method. As a result, you could put the extension method in it's own class, `ExtensionMethods` for example, and then add your extension method within it as a public static method. – Thebigcheeze Jul 08 '11 at 17:30
2

Although I like the idea of a constructor accepting a string more, you could define an implicit or explicit conversion operator between RemoteFileDP and string:

 class RemoteFileDP
 {
      ....

      public static implicit operator RemoteFileDP(string locationDictionary)
      {
           //return a new and appropiately initialized RemoteFileDP object.
           //you could mix this solution with Anna's the following way:
           return new RemoteFileDP(locationDictionary);
      }
 }

This way you could actually write:

 RemoteFileDP remoteFile = locationDirectory;

or, if the conversion operator were to be explicit:

 RemoteFileDP remoteFile = (RemoteFileDP)locationDirectory;

Still I insist, Anna Lear's solution is better as implicit or explicit conversion doesn't really seem to be the best fit for this kind of case. For instance, if the conversion can fail due to an invalid locationDictionary value then I wouldn't recommend this path. If the conversion is always succesful no matter what value locationDictionary is (barring null) then it could be a valid solution to your problem.

I'm just putting it on the table as I think you might find it useful to know about explicit and implicit conversions in C#, in case you didn't already.

InBetween
  • 32,319
  • 3
  • 50
  • 90
  • Thank you for your response! I did try the explicit conversion first (had to study up on it first) but couldn't seem to get it to work. So I went the other path of Activator.CreateInstance since that seemed more what I was looking for. But yes, I'm always open to learning new things. – Invaderleige Jul 08 '11 at 00:12
  • @Invaderleige: All solutions posted amount to the same basically. At the end you have to properly initialize a `RemoteFileDP` object given a certain `string`. The conversion operator just saves you a few keystrokes each time you initialize a `RemoteFileDP` from a string. (See edit to my answer on how to integrate Anna's solution with conversion operators). – InBetween Jul 08 '11 at 00:17
  • Thank you for the update and showing how I could use Anna's solution with yours. – Invaderleige Jul 08 '11 at 13:20
1

You're missing a constructor that takes a string as a parameter. Try your code with

public RemoteFileDP(string locationDirectory)
{
    // do stuff with locationDirectory to initialize RemoteFileDP appropriately
}

Of course, if you do that, why not just call the constructor directly?

RemoteFileDP remoteFile = new RemoteFileDP(locationDirectory);
Adam Lear
  • 38,111
  • 12
  • 81
  • 101
  • Well this might work as well. Sometimes it seems that the simple things get overlooked. I will try this as well and let you know. – Invaderleige Jul 07 '11 at 23:28
  • Yeah this worked! Thanks "Anna Lear". Now I need to try the other approach offered. – Invaderleige Jul 07 '11 at 23:51
  • @Invaderleige Glad to hear that. :) If you end up going with this approach, please click the checkmark to the left of my answer to [accept it](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). – Adam Lear Jul 07 '11 at 23:54