I want to have a constructor that is blank and a constructor overload that accepts a parameter and assign it to a public property.
This is where I am stuck:
type TemplateService() =
interface ITemplateService with
//Properties
member TemplateDirectory = ""
//Constructors
new (templateDirectory:string) = //Error here.
if (templateDirectory == null) then
raise (new System.ArgumentNullException("templateDirectory"))
TemplateDirectory = templateDirectory;
It gives me the error: `Unexpected keyword 'new' in the Object expression. Expected 'member', 'override' or other token.
If I use member
, the property TemplateDirectory
gives this error:
This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'
3 Answers 3
You could try this.
type TemplateService(templateDirectory : string) =
do
if templateDirectory = null then nullArg "templateDirectory"
new() = TemplateService("")
interface ITemplateService with
member this.TemplateDirectory = templateDirectory
-
what if I wanted to check if
d
is null or empty before assigning? Such as throwing an error before it.Shawn Mclean– Shawn Mclean03/15/2011 03:58:20Commented Mar 15, 2011 at 3:58 -
But I only need to do this test for the constructor that accepts an arguement. If I do
new TemplateService()
, then it will throw an error.Shawn Mclean– Shawn Mclean03/15/2011 05:04:14Commented Mar 15, 2011 at 5:04 -
I don't think the above code snippet will throw exception if you do new TemplateService(). It will be good if i can see your actual code.Nyi Nyi– Nyi Nyi03/15/2011 09:22:00Commented Mar 15, 2011 at 9:22
Unfortunately if you want to use an interface and pass the value to the constructor nyinyithann answer is correct. You can set public properties in a constructor call like this.
type TemplateService() =
let mutable templateDirectory = ""
member this.TemplateDirectory
with get() = templateDirectory
and set directory =
if directory = null then
raise (new System.ArgumentNullException "templateDirectory")
templateDirectory <- directory
let template = TemplateService(TemplateDirectory = "root")
Now if you want to use an interface this won't work.
type ITemplateService =
abstract TemplateDirectory : string with get, set
type TemplateService() =
let mutable templateDirectory = ""
interface ITemplateService with
member this.TemplateDirectory
with get() = templateDirectory
and set directory =
if directory = null then
raise (new System.ArgumentNullException "templateDirectory")
templateDirectory <- directory
let template = TemplateService(TemplateDirectory = "root") // error
You're forced to use this ugly thing.
let template = TemplateService()
(template :> ITemplateService).TemplateDirectory <- "root"
-
My recommendation when you want interface and normal access is to simply define it twice, once outside the interface, and a wrapper within the interface.Guvante– Guvante03/15/2011 19:24:55Commented Mar 15, 2011 at 19:24
You are putting your constructor in the definition of the interface, and that is the cause for the error. Also you are attempting to store a value to a get only property, instead you should use a backing store.
Finally I would recommend nyinyithann's version over this, since it is more inline with the usual F# style (minimal mutables), just hoping to give a version closer to yours in case it is helpful.
type TemplateService() =
let mutable directory = ""
interface ITemplateService with
//Properties
member this.TemplateDirectory = directory
//Constructors
new (templateDirectory:string) =
if (templateDirectory = null) then
raise (new System.ArgumentNullException("templateDirectory"))
directory <- templateDirectory;