Handling different logic based on type
<p>I have <code>class Foo&lt;T&gt;</code> and an instance method <code>Foo&lt;T&gt;.M</code> with return type <code>T</code> and signature <code>M(Bar bar)</code>. There is a constraint on <code>T</code> (<code>T : AbstractBaseClass</code>) so that I'm certain that <code>T</code> has a property <code>T.SomeProperty</code> (and a parameterless constructor constraint). Let's say that <code>M</code> has to set the value of <code>T.SomeProperty</code> based on <code>bar</code> as well on the concrete type of <code>T</code>. I do not want my code to look like</p>

<pre><code>T t = new T();
if(typeof(T) == T1) {
     T.SomeProperty = // some function of bar
}
else if(typeof(T) == T2) {
     T.SomeProperty = // some function of bar
}
else if(typeof(T) == T3) {
     T.SomeProperty == // some function of bar
}
</code></pre>

<p>I do not want to put an instance method on <code>T</code> that takes in values from <code>Bar</code> to populate <code>T.SomeProperty</code> because that will make my <code>T</code>s have a dependency on some things that I do not want it to them a dependency on.</p>

<p>What is my best option here? </p>

<p>Here's what I mean:</p>

<pre><code>class AbstractBaseClass {
    public int SomeProperty { get; set; }
}

class Foo&lt;T&gt; where T : AbstractBaseClass, new() {
    public T M(Bar bar) {
        T t = new T();
        t.SomeProperty = // function of bar, typeof(T)
        return t;
    }
}
</code></pre>

<p>How to write <code>M</code> but avoid type-by-type logic on the type parameter <code>T</code>?</p>

<p>Edit:</p>

<p>What about this? This is riffing on <a href="http://stackoverflow.com/questions/7337972/handling-different-logic-based-on-type/7338372#7338372">Corey's idea</a>:</p>

<pre><code>interface ISomePropertyStrategy&lt;T&gt; {
    int GetSomeProperty(Bar bar);
}

class SomePropertyStrategyForConcreteClass1 :
    ISomePropertyStrategy&lt;ConcreteClass1&gt; {
    public int GetSomeProperty(Bar bar) { return bar.MagicValue + 73; }
}

class SomePropertyStrategyForConcreteClass2 :
    ISomePropertyStrategy&lt;ConcreteClass2&gt; {
    public int GetSomeProperty(Bar bar) { return bar.MagicValue - 12; }
}

class Foo&lt;T&gt; where T : AbstractBaseClass, new() {
    private readonly ISomePropertyStrategy&lt;T&gt; strategy;
    public Foo&lt;T&gt;(ISomePropertyStrategy&lt;T&gt; strategy) {
        this.stragety = strategy;
    }
    public T M(Bar bar) {
        T t = new T();
        t.SomeProperty = this.strategy.GetSomeProperty(bar);
        return t;
    }
 }
</code></pre>

<p>The only thing I don't like about this is that it uses a generic interface where the generic type parameter never appears in the interface. I think I once saw a comment from Eric Lippert where he said that wasn't a good idea, but I can't remember. Sorry.</p>
