Reputation: 61463
I want to have an overloaded constructor where I change the value of the base class depending if the "isFirstPost" is set. If it's a first post, I want the rowkey = 000000. If it's not a first post, then make it a number.
Don't really think of this as an Azure problem... but I'm more interested in the C# language and making a conditional parameter influence the setting of the base class. I'm not sure how to do this.
public class ForumPost : TableServiceEntity
{
public ForumPost(string partitionKey, string rowKey): base(partitionKey, rowKey)
{
}
public ForumPost(ForumThread ParentThread, bool IsFirstPost)
{
if (IsFirstPost)
{
//call constuctor with special values for base class
//set baseclass rowkey = 0000000
}
else {
//set baseclass rowkey = 1111111111
}
}
}
Upvotes: 1
Views: 851
Reputation: 27727
This isn't possible because the base constructor must be called before the current class's constructor. What you can do is define a static function that will pass the correct id to the base constructor.
public class ForumPost : TableServiceEntity
{
public ForumPost(ForumThread ParentThread, bool IsFirstPost)
: base(ParentThread, GetID(IsFirstPost))
{
}
static string GetID(bool IsFirstPost)
{
return IsFirstPost ? "00000" : "11111";
}
}
Upvotes: 5
Reputation: 56477
Just do this:
public class ForumPost : TableServiceEntity {
public ForumPost(ForumThread ParentThread, bool IsFirstPost)
: base("partitionkey", IsFirstPost ? "0000000" : "1111111") {
}
}
Note: I don't know what you want to pass as a partition key though.
UPDATE: to understand what this construct can take, we can take a look at the C# specification.
In the C# grammar we find these entries:
constructor-initializer:
: base ( argument-listopt )
: this ( argument-listopt )
argument-list:
argument
argument-list , argument
argument:
expression
ref variable-reference
out variable-reference
This, in turn, expands to all kinds of expressions that the language supports (look in section C.2.4). This includes method invocations, mathematical expressions, the ternary conditional operator, and many others.
In section 10.11.1 (Constructor initializers) of the spec, we find this:
The scope of the parameters given by the formal-parameter-list of an instance constructor declaration includes the constructor initializer of that declaration. Thus, a constructor initializer is permitted to access the parameters of the constructor. [...] An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name.
So, you can treat it just like any method invocation. You have access to the arguments to the constructor, but not to the instance being created. Which means that, if your logic involves any instance members of the instance being constructed, you'll have to redesign your class to separate them.
I think the answer that I gave (with the conditional operator) is the most straighforward for your example. We can also take it to the other extreme, and use a factory method to get a strategy for that logic:
public class ForumPost : TableServiceEntity {
public ForumPost(ForumThread ParentThread, bool IsFirstPost)
: base("partitionkey",
RowKeyStrategyFactory.Create().ResolveRowKey(IsFirstPost)) {
}
}
Here you see a static factory method call, that returns an instance of a strategy, followed by an instance call on the strategy virtual method that runs the desired logic. The concrete strategy class would be decided based, e.g., in configuration, and would contain the logic to generate the right row key given its parameter.
As you can see, there's no single answer for the question, only you can decide based on your design and constraints. But by understanding what the construct can handle, you're better informed to make a good decision.
Upvotes: 2