2

When trying to set a property added in .Net 4.5 on a system which only has .Net 4.0 you get MissingMemberException (https://msdn.microsoft.com/en-us/library/system.missingmemberexception(v=vs.110).aspx). However you can only catch this when using reflection, otherwise it is an uncatchable JIT exception. (Why is it not possible to catch MissingMethodException?)

So I changed my code from:

client.DeliveryFormat = SmtpDeliveryFormat.International;

to

var p = client.GetType().GetProperty("DeliveryFormat");
if(p!=null)
p.SetValue(client, SmtpDeliveryFormat.International);

However now I get a TypeLoadException thrown instead about SmtpDeliveryFormat because this enum was only added in 4.5 also.

How can I work around this second issue?

Community
  • 1
  • 1
Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • Just curious, is it even possible to run a 4.5 app on a system without the required framework? or you mean you're dynamically loading libraries from older versions? – Gusman May 13 '16 at 10:48
  • Why cant you check for the existence of the property before settings its value? – thehennyy May 13 '16 at 10:48
  • Also, the TypeLoadException tells you which type cannot be loaded? – Gusman May 13 '16 at 10:52
  • @thehennyy I suspect the problem is not because the set but the GetType, it will try to load the "Type" class from the V4.5 framework and it doesn't exists as the framework is not installed. – Gusman May 13 '16 at 10:53
  • 1
    If the code really runs, you can check "Environment.Version" to retrieve the framework version and then do or don't do the calls to the property. – Gusman May 13 '16 at 10:56
  • Surprisingly it runs just fine - I expected otherwise myself. I just realised the issue is `SmtpDeliveryFormat` doesn't exist in 4.5 either; this is the type the exception is telling me about. I'll update the question... – Mr. Boy May 13 '16 at 10:58
  • @Gusman I didn't realise checking the .Net version was as easy as that. CAn I rely on JIT not to try compiling my code if it's not used? – Mr. Boy May 13 '16 at 11:01
  • No, it will be compiled, but if the function where the code is allocated is not executed it should not rise any exception, so creating two functions, one for 4.5 and other for 4.0 and then only call the correct one should give no problem at all. – Gusman May 13 '16 at 11:03

1 Answers1

1

One option is to go with reflection all the way:

var prop = client.GetType().GetProperty("DeliveryFormat");
if (prop != null) {
    var enumType = typeof (SmtpClient).Assembly.GetType("System.Net.Mail.SmtpDeliveryFormat");
    prop.SetValue(client, Enum.Parse(enumType, "International", null));                                
}

This should not throw missing method or type load exceptions in your case.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • You're going to love this, but that overload of `PropertyInfo.SetValue` doesn't exist in 4.0 either! https://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.setvalue(v=vs.100).aspx – Mr. Boy May 13 '16 at 11:37
  • @Mr.Boy well then use one that exists :) prop.SetValue(client, Enum.Parse(enumType, "International", null)); – Evk May 13 '16 at 11:42
  • Yeah I was just testing that before posting :) – Mr. Boy May 13 '16 at 11:45