Create method dynamically where return type is known at compiletime











up vote
2
down vote

favorite












given following class:



public class Stock {
public string Name;
public double Price;
}


and I have following DataFactory:



public class DataFactory {
public Stock Stock = new Stock();

public DataFactory Name(string name) {
Stock.name = name;
return this;
}

public DataFactory Price(double price) {
Stock.Price = price;
return this;
}
}


can following code:



.....
new DataFactory().Name("ATVI").Price(50)
....


be written as:



....
new DataFactory().ATVI().Price(50)
....


without implementing ATVI() on the factory?
This will work if i create the method dynamically beforehand. But is this also possible without knowing what method will be called? So i am looking for some hook at lifetime that notifies me about unknown properties/methods.



And if this works, can Price() at compile time be called with intellisense?



No idea how this can be called so sorry if duplicate threads exist.



Best regards
Josef










share|improve this question






















  • Do you just hate writing string literals, or do you just hate writing Name?
    – Sweeper
    2 days ago






  • 1




    If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
    – Klaus Gütter
    2 days ago










  • @Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
    – Josef Biehler
    2 days ago










  • @KlausGütter Thanks. I will try this.
    – Josef Biehler
    2 days ago















up vote
2
down vote

favorite












given following class:



public class Stock {
public string Name;
public double Price;
}


and I have following DataFactory:



public class DataFactory {
public Stock Stock = new Stock();

public DataFactory Name(string name) {
Stock.name = name;
return this;
}

public DataFactory Price(double price) {
Stock.Price = price;
return this;
}
}


can following code:



.....
new DataFactory().Name("ATVI").Price(50)
....


be written as:



....
new DataFactory().ATVI().Price(50)
....


without implementing ATVI() on the factory?
This will work if i create the method dynamically beforehand. But is this also possible without knowing what method will be called? So i am looking for some hook at lifetime that notifies me about unknown properties/methods.



And if this works, can Price() at compile time be called with intellisense?



No idea how this can be called so sorry if duplicate threads exist.



Best regards
Josef










share|improve this question






















  • Do you just hate writing string literals, or do you just hate writing Name?
    – Sweeper
    2 days ago






  • 1




    If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
    – Klaus Gütter
    2 days ago










  • @Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
    – Josef Biehler
    2 days ago










  • @KlausGütter Thanks. I will try this.
    – Josef Biehler
    2 days ago













up vote
2
down vote

favorite









up vote
2
down vote

favorite











given following class:



public class Stock {
public string Name;
public double Price;
}


and I have following DataFactory:



public class DataFactory {
public Stock Stock = new Stock();

public DataFactory Name(string name) {
Stock.name = name;
return this;
}

public DataFactory Price(double price) {
Stock.Price = price;
return this;
}
}


can following code:



.....
new DataFactory().Name("ATVI").Price(50)
....


be written as:



....
new DataFactory().ATVI().Price(50)
....


without implementing ATVI() on the factory?
This will work if i create the method dynamically beforehand. But is this also possible without knowing what method will be called? So i am looking for some hook at lifetime that notifies me about unknown properties/methods.



And if this works, can Price() at compile time be called with intellisense?



No idea how this can be called so sorry if duplicate threads exist.



Best regards
Josef










share|improve this question













given following class:



public class Stock {
public string Name;
public double Price;
}


and I have following DataFactory:



public class DataFactory {
public Stock Stock = new Stock();

public DataFactory Name(string name) {
Stock.name = name;
return this;
}

public DataFactory Price(double price) {
Stock.Price = price;
return this;
}
}


can following code:



.....
new DataFactory().Name("ATVI").Price(50)
....


be written as:



....
new DataFactory().ATVI().Price(50)
....


without implementing ATVI() on the factory?
This will work if i create the method dynamically beforehand. But is this also possible without knowing what method will be called? So i am looking for some hook at lifetime that notifies me about unknown properties/methods.



And if this works, can Price() at compile time be called with intellisense?



No idea how this can be called so sorry if duplicate threads exist.



Best regards
Josef







c# visual-studio-2017






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 days ago









Josef Biehler

15710




15710












  • Do you just hate writing string literals, or do you just hate writing Name?
    – Sweeper
    2 days ago






  • 1




    If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
    – Klaus Gütter
    2 days ago










  • @Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
    – Josef Biehler
    2 days ago










  • @KlausGütter Thanks. I will try this.
    – Josef Biehler
    2 days ago


















  • Do you just hate writing string literals, or do you just hate writing Name?
    – Sweeper
    2 days ago






  • 1




    If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
    – Klaus Gütter
    2 days ago










  • @Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
    – Josef Biehler
    2 days ago










  • @KlausGütter Thanks. I will try this.
    – Josef Biehler
    2 days ago
















Do you just hate writing string literals, or do you just hate writing Name?
– Sweeper
2 days ago




Do you just hate writing string literals, or do you just hate writing Name?
– Sweeper
2 days ago




1




1




If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
– Klaus Gütter
2 days ago




If you derive your datafactory from DynamicObject, you could override TryGetMethod. But I doubt there is a way to provide intellisense,
– Klaus Gütter
2 days ago












@Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
– Josef Biehler
2 days ago




@Sweeper I understand that this sounds a bit weird. But currently I want to write unit tests for a tool. To do this I will need some test data. I though about moving all those unwanted stuff into a data factory. Then I was thinking of how I can remove the need to write Name() all over again. The idea is that if any string literal is given, i always know that this is the stock symbol. Of course it will be a fancy feature if this works. So it is more experimentally in my case.
– Josef Biehler
2 days ago












@KlausGütter Thanks. I will try this.
– Josef Biehler
2 days ago




@KlausGütter Thanks. I will try this.
– Josef Biehler
2 days ago












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










Assuming you have a finite pre-defined set of text literals that does not change often, you could just generate an enumeration (or even a class of string constants) using T4 templates for example, and use it like:
DataFactory.Name(Tickers.ATVI).Price(50)

That would be an approach that best matches semantics of the problem and abilities of C# language and tooling.



By the way, that method chaining you're planning to use is a combination of builder pattern and fluent interface, see an example in c#



If you still want to have this concealed as a method call, you have a couple of options:




  1. Pre - Generate list of methods using T4 templates in a partial class or as extension methods to your data factory. You could select a list of literals from you data store inside your T4 template. This is a fairly common approach. Since you will have the methods pre-generated, itellisence will work with this approach. read more about T4

  2. Use DLR and dynamic. This will defer method lookup until runtime, and you can create a custom dynamic object that will accept any method call, and then take that method name and pass it as an argument to your Name method. Intellisence won't work with this approach since you don't have any metadata in the assembly regarding your methods. How to create a dynamic object

  3. Use dynamic and additionally create an intellisence extension, see Custom Intellisense Extension for more details


You coud go even further, and write an Roslyn analyzer, and install it in your Visual Studio to have automatic code fixes from DataFactory().Name("ATVI") to DataFactory().ATVI(), that is - if you have the time/resource. Check out example of code analyzer



As always, the answer is "it depends", and context is everything, so it is hard to tell which solution will be best for you.
I would rather go for the simplest one 1), especially keeping in mind the complexity and maintenance cost of 2) and 3)



Please let me know if you need more details on any of the options
Hope it helps!






share|improve this answer























  • Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
    – Josef Biehler
    2 days ago










  • Glad I could help, @JosefBiehler!
    – ironstone13
    2 days ago


















up vote
0
down vote













the following code



new DataFactory().Name("ATVI").Price(50)


cannot be written as



new DataFactory().ATVI().Price(50)


in fact, none of those codes works. because you can't get function "Price" from the function "Name" and "ATVI()" is not a valid function



I'm not sore what you're trying to accomplish, the given code will return a function.
but if I'm not mistaken you to want to set "Price" by "Name".
then what I think you need is the Class Dictionary



I tried to come up with a nice function or anything like that but I don't really know what you're are after...






share|improve this answer





















  • As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
    – Josef Biehler
    2 days ago











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53349880%2fcreate-method-dynamically-where-return-type-is-known-at-compiletime%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Assuming you have a finite pre-defined set of text literals that does not change often, you could just generate an enumeration (or even a class of string constants) using T4 templates for example, and use it like:
DataFactory.Name(Tickers.ATVI).Price(50)

That would be an approach that best matches semantics of the problem and abilities of C# language and tooling.



By the way, that method chaining you're planning to use is a combination of builder pattern and fluent interface, see an example in c#



If you still want to have this concealed as a method call, you have a couple of options:




  1. Pre - Generate list of methods using T4 templates in a partial class or as extension methods to your data factory. You could select a list of literals from you data store inside your T4 template. This is a fairly common approach. Since you will have the methods pre-generated, itellisence will work with this approach. read more about T4

  2. Use DLR and dynamic. This will defer method lookup until runtime, and you can create a custom dynamic object that will accept any method call, and then take that method name and pass it as an argument to your Name method. Intellisence won't work with this approach since you don't have any metadata in the assembly regarding your methods. How to create a dynamic object

  3. Use dynamic and additionally create an intellisence extension, see Custom Intellisense Extension for more details


You coud go even further, and write an Roslyn analyzer, and install it in your Visual Studio to have automatic code fixes from DataFactory().Name("ATVI") to DataFactory().ATVI(), that is - if you have the time/resource. Check out example of code analyzer



As always, the answer is "it depends", and context is everything, so it is hard to tell which solution will be best for you.
I would rather go for the simplest one 1), especially keeping in mind the complexity and maintenance cost of 2) and 3)



Please let me know if you need more details on any of the options
Hope it helps!






share|improve this answer























  • Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
    – Josef Biehler
    2 days ago










  • Glad I could help, @JosefBiehler!
    – ironstone13
    2 days ago















up vote
2
down vote



accepted










Assuming you have a finite pre-defined set of text literals that does not change often, you could just generate an enumeration (or even a class of string constants) using T4 templates for example, and use it like:
DataFactory.Name(Tickers.ATVI).Price(50)

That would be an approach that best matches semantics of the problem and abilities of C# language and tooling.



By the way, that method chaining you're planning to use is a combination of builder pattern and fluent interface, see an example in c#



If you still want to have this concealed as a method call, you have a couple of options:




  1. Pre - Generate list of methods using T4 templates in a partial class or as extension methods to your data factory. You could select a list of literals from you data store inside your T4 template. This is a fairly common approach. Since you will have the methods pre-generated, itellisence will work with this approach. read more about T4

  2. Use DLR and dynamic. This will defer method lookup until runtime, and you can create a custom dynamic object that will accept any method call, and then take that method name and pass it as an argument to your Name method. Intellisence won't work with this approach since you don't have any metadata in the assembly regarding your methods. How to create a dynamic object

  3. Use dynamic and additionally create an intellisence extension, see Custom Intellisense Extension for more details


You coud go even further, and write an Roslyn analyzer, and install it in your Visual Studio to have automatic code fixes from DataFactory().Name("ATVI") to DataFactory().ATVI(), that is - if you have the time/resource. Check out example of code analyzer



As always, the answer is "it depends", and context is everything, so it is hard to tell which solution will be best for you.
I would rather go for the simplest one 1), especially keeping in mind the complexity and maintenance cost of 2) and 3)



Please let me know if you need more details on any of the options
Hope it helps!






share|improve this answer























  • Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
    – Josef Biehler
    2 days ago










  • Glad I could help, @JosefBiehler!
    – ironstone13
    2 days ago













up vote
2
down vote



accepted







up vote
2
down vote



accepted






Assuming you have a finite pre-defined set of text literals that does not change often, you could just generate an enumeration (or even a class of string constants) using T4 templates for example, and use it like:
DataFactory.Name(Tickers.ATVI).Price(50)

That would be an approach that best matches semantics of the problem and abilities of C# language and tooling.



By the way, that method chaining you're planning to use is a combination of builder pattern and fluent interface, see an example in c#



If you still want to have this concealed as a method call, you have a couple of options:




  1. Pre - Generate list of methods using T4 templates in a partial class or as extension methods to your data factory. You could select a list of literals from you data store inside your T4 template. This is a fairly common approach. Since you will have the methods pre-generated, itellisence will work with this approach. read more about T4

  2. Use DLR and dynamic. This will defer method lookup until runtime, and you can create a custom dynamic object that will accept any method call, and then take that method name and pass it as an argument to your Name method. Intellisence won't work with this approach since you don't have any metadata in the assembly regarding your methods. How to create a dynamic object

  3. Use dynamic and additionally create an intellisence extension, see Custom Intellisense Extension for more details


You coud go even further, and write an Roslyn analyzer, and install it in your Visual Studio to have automatic code fixes from DataFactory().Name("ATVI") to DataFactory().ATVI(), that is - if you have the time/resource. Check out example of code analyzer



As always, the answer is "it depends", and context is everything, so it is hard to tell which solution will be best for you.
I would rather go for the simplest one 1), especially keeping in mind the complexity and maintenance cost of 2) and 3)



Please let me know if you need more details on any of the options
Hope it helps!






share|improve this answer














Assuming you have a finite pre-defined set of text literals that does not change often, you could just generate an enumeration (or even a class of string constants) using T4 templates for example, and use it like:
DataFactory.Name(Tickers.ATVI).Price(50)

That would be an approach that best matches semantics of the problem and abilities of C# language and tooling.



By the way, that method chaining you're planning to use is a combination of builder pattern and fluent interface, see an example in c#



If you still want to have this concealed as a method call, you have a couple of options:




  1. Pre - Generate list of methods using T4 templates in a partial class or as extension methods to your data factory. You could select a list of literals from you data store inside your T4 template. This is a fairly common approach. Since you will have the methods pre-generated, itellisence will work with this approach. read more about T4

  2. Use DLR and dynamic. This will defer method lookup until runtime, and you can create a custom dynamic object that will accept any method call, and then take that method name and pass it as an argument to your Name method. Intellisence won't work with this approach since you don't have any metadata in the assembly regarding your methods. How to create a dynamic object

  3. Use dynamic and additionally create an intellisence extension, see Custom Intellisense Extension for more details


You coud go even further, and write an Roslyn analyzer, and install it in your Visual Studio to have automatic code fixes from DataFactory().Name("ATVI") to DataFactory().ATVI(), that is - if you have the time/resource. Check out example of code analyzer



As always, the answer is "it depends", and context is everything, so it is hard to tell which solution will be best for you.
I would rather go for the simplest one 1), especially keeping in mind the complexity and maintenance cost of 2) and 3)



Please let me know if you need more details on any of the options
Hope it helps!







share|improve this answer














share|improve this answer



share|improve this answer








edited 2 days ago

























answered 2 days ago









ironstone13

2,055921




2,055921












  • Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
    – Josef Biehler
    2 days ago










  • Glad I could help, @JosefBiehler!
    – ironstone13
    2 days ago


















  • Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
    – Josef Biehler
    2 days ago










  • Glad I could help, @JosefBiehler!
    – ironstone13
    2 days ago
















Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
– Josef Biehler
2 days ago




Very helpful! Thanks for all the options. I think I will try all of them and decide then what I should use. I will come back if I need further assistance.
– Josef Biehler
2 days ago












Glad I could help, @JosefBiehler!
– ironstone13
2 days ago




Glad I could help, @JosefBiehler!
– ironstone13
2 days ago












up vote
0
down vote













the following code



new DataFactory().Name("ATVI").Price(50)


cannot be written as



new DataFactory().ATVI().Price(50)


in fact, none of those codes works. because you can't get function "Price" from the function "Name" and "ATVI()" is not a valid function



I'm not sore what you're trying to accomplish, the given code will return a function.
but if I'm not mistaken you to want to set "Price" by "Name".
then what I think you need is the Class Dictionary



I tried to come up with a nice function or anything like that but I don't really know what you're are after...






share|improve this answer





















  • As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
    – Josef Biehler
    2 days ago















up vote
0
down vote













the following code



new DataFactory().Name("ATVI").Price(50)


cannot be written as



new DataFactory().ATVI().Price(50)


in fact, none of those codes works. because you can't get function "Price" from the function "Name" and "ATVI()" is not a valid function



I'm not sore what you're trying to accomplish, the given code will return a function.
but if I'm not mistaken you to want to set "Price" by "Name".
then what I think you need is the Class Dictionary



I tried to come up with a nice function or anything like that but I don't really know what you're are after...






share|improve this answer





















  • As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
    – Josef Biehler
    2 days ago













up vote
0
down vote










up vote
0
down vote









the following code



new DataFactory().Name("ATVI").Price(50)


cannot be written as



new DataFactory().ATVI().Price(50)


in fact, none of those codes works. because you can't get function "Price" from the function "Name" and "ATVI()" is not a valid function



I'm not sore what you're trying to accomplish, the given code will return a function.
but if I'm not mistaken you to want to set "Price" by "Name".
then what I think you need is the Class Dictionary



I tried to come up with a nice function or anything like that but I don't really know what you're are after...






share|improve this answer












the following code



new DataFactory().Name("ATVI").Price(50)


cannot be written as



new DataFactory().ATVI().Price(50)


in fact, none of those codes works. because you can't get function "Price" from the function "Name" and "ATVI()" is not a valid function



I'm not sore what you're trying to accomplish, the given code will return a function.
but if I'm not mistaken you to want to set "Price" by "Name".
then what I think you need is the Class Dictionary



I tried to come up with a nice function or anything like that but I don't really know what you're are after...







share|improve this answer












share|improve this answer



share|improve this answer










answered 2 days ago









the Wongfon Semicolon

4317




4317












  • As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
    – Josef Biehler
    2 days ago


















  • As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
    – Josef Biehler
    2 days ago
















As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
– Josef Biehler
2 days ago




As you can see in my code example, Name() returns an instance of type DataFactory and not a function? So yes, this code should work, though i have not tested it but written it on the fly while writing this question. Maybe I don't understand exactly your point :-)
– Josef Biehler
2 days ago


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53349880%2fcreate-method-dynamically-where-return-type-is-known-at-compiletime%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Costa Masnaga

Fotorealismo

Sidney Franklin