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
c# visual-studio-2017
add a comment |
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
c# visual-studio-2017
Do you just hate writing string literals, or do you just hate writingName
?
– 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
add a comment |
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
c# visual-studio-2017
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
c# visual-studio-2017
asked 2 days ago
Josef Biehler
15710
15710
Do you just hate writing string literals, or do you just hate writingName
?
– 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
add a comment |
Do you just hate writing string literals, or do you just hate writingName
?
– 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
add a comment |
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:
- 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 yourT4
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
- Use
DLR
anddynamic
. 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 yourName
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
- 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!
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
add a comment |
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...
As you can see in my code example,Name()
returns an instance of typeDataFactory
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
add a comment |
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:
- 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 yourT4
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
- Use
DLR
anddynamic
. 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 yourName
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
- 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!
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
add a comment |
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:
- 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 yourT4
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
- Use
DLR
anddynamic
. 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 yourName
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
- 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!
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
add a comment |
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:
- 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 yourT4
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
- Use
DLR
anddynamic
. 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 yourName
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
- 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!
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:
- 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 yourT4
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
- Use
DLR
anddynamic
. 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 yourName
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
- 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!
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
add a comment |
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
add a comment |
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...
As you can see in my code example,Name()
returns an instance of typeDataFactory
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
add a comment |
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...
As you can see in my code example,Name()
returns an instance of typeDataFactory
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
add a comment |
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...
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...
answered 2 days ago
the Wongfon Semicolon
4317
4317
As you can see in my code example,Name()
returns an instance of typeDataFactory
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
add a comment |
As you can see in my code example,Name()
returns an instance of typeDataFactory
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
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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