admin管理员组文章数量:1379438
I have an interface function called SetParametersAsync(BaseClass myObject)
, the interface is not mine so I can't change the signature.
Inside the function there's an if/else
statement which checks the type of the object and invokes methods. Now there's a new type to be added, which is a generic type DerivedClass<T> : BaseClass where T : struct
The Type of T is not relevant here, I want to call the same methods on the derived class object for all types of T.
Here's an incomplete example code of what I need:
// existing class, can't alter the signature
public class ExampleClass : IParameterMethods
{
// inherited from interface, can't alter the signature
public async Task<bool> SetParametersAsync(BaseClass myObject)
{
if (myObject is MyClassA a)
{
a.DoThis();
MethodThatExpectsAMyClassAParameter(a);
}
// ...other ifs
// NOW THIS IS WHAT I NEED TO ADD FOR THE NEW GENERIC CLASS:
else if (myObject is DerivedClass<T> derived)
{
derived.MethodFromGenericClass();
MethodThatExpectsDerivedClassTParameter(derived);
}
}
// this is a method I need to call with my generic object, as you can see the exact type of T does not matter, it just has to be a struct type that's all
private void MethodThatExpectsDerivedClassTParameter(DerivedClass<T> derived) where T: struct
{
...
}
Of course the above doesn't compile because T is not known. I don't want to add "ifs" for all possible types of T, so what can I do to solve this problem?
I have an interface function called SetParametersAsync(BaseClass myObject)
, the interface is not mine so I can't change the signature.
Inside the function there's an if/else
statement which checks the type of the object and invokes methods. Now there's a new type to be added, which is a generic type DerivedClass<T> : BaseClass where T : struct
The Type of T is not relevant here, I want to call the same methods on the derived class object for all types of T.
Here's an incomplete example code of what I need:
// existing class, can't alter the signature
public class ExampleClass : IParameterMethods
{
// inherited from interface, can't alter the signature
public async Task<bool> SetParametersAsync(BaseClass myObject)
{
if (myObject is MyClassA a)
{
a.DoThis();
MethodThatExpectsAMyClassAParameter(a);
}
// ...other ifs
// NOW THIS IS WHAT I NEED TO ADD FOR THE NEW GENERIC CLASS:
else if (myObject is DerivedClass<T> derived)
{
derived.MethodFromGenericClass();
MethodThatExpectsDerivedClassTParameter(derived);
}
}
// this is a method I need to call with my generic object, as you can see the exact type of T does not matter, it just has to be a struct type that's all
private void MethodThatExpectsDerivedClassTParameter(DerivedClass<T> derived) where T: struct
{
...
}
Of course the above doesn't compile because T is not known. I don't want to add "ifs" for all possible types of T, so what can I do to solve this problem?
Share Improve this question edited Mar 20 at 11:15 sth_Weird asked Mar 20 at 11:00 sth_Weirdsth_Weird 6688 silver badges16 bronze badges 8 | Show 3 more comments1 Answer
Reset to default 0I don't know if that's what you are looking for, but this is how I would probably tackle this:
Some explanations in comments...
using System;
public class Program : ICallHost
{
public static void Main()
{
var p = new Program();
var test = new DerivedClass<DateTimeOffset>();
p.Driver(test);
}
private void Driver(BaseClass bc)
{
// if ... else if ... goes here
if(bc is DerivedClass dc) // You do not care about T, here.
{
dc.ThatOtherMethod();
// Tell dc to call back
// We do not have a means without reflection or test every possible T
// which T dc actually is ...
dc.CallTheMethod(this);
}
}
// You _do_ care about T here
public void TheMethod<T>(DerivedClass<T> dc) where T : struct
{
Console.WriteLine("Hello from {0}", dc.GetType().FullName);
}
}
// Interfaces for double-dispatch visitor pattern
public interface IVisitor
{
void CallTheMethod(ICallHost host);
}
public interface ICallHost
{
void TheMethod<T>(DerivedClass<T> dc) where T : struct;
}
public abstract class BaseClass
{}
// intermediate non-generic derived class to detect the class family
public abstract class DerivedClass : BaseClass, IVisitor
{
// All implementations are abstract here, so DerivedClass<T> has to implement.
// You could add common methods with implementation here, too.
public abstract void CallTheMethod(ICallHost host);
public abstract void ThatOtherMethod();
}
public sealed class DerivedClass<T> : DerivedClass where T : struct
{
// perform the callback passing this instance as concrete generic type
// because this instance knows what T it is.
public override void CallTheMethod(ICallHost host) => host.TheMethod(this);
public override void ThatOtherMethod(){
Console.WriteLine("That other method.");
}
}
See it in action : Fiddle
Output:
That other method. Hello from DerivedClass`1[[System.DateTimeOffset, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
本文标签: cCast object to MyGenericTypeltTgt when type of T is not importantStack Overflow
版权声明:本文标题:c# - Cast object to MyGenericType<T> when type of T is not important - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744414794a2605138.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
BaseClass
? – Jon Skeet Commented Mar 20 at 11:03BaseClass
you need to define an interfaces without generics that is implemented byDerivedClass<T>
. Yourif
checks for that interface instead ofDerivedClass<T>
. – Sebastian Schumann Commented Mar 20 at 11:06where T : struct
? What doesMethodThatExpectsDerivedClassTParameter
actually do? Please give a minimal reproducible example, also with the definition of the base and derived classes. – Charlieface Commented Mar 20 at 11:07DerivedClass : BaseClass
from which there isDerivedClass<T> : DerivedClass
? – Fildor Commented Mar 20 at 11:12DerivedClass<T>
could implement a non-generic interface, and you put the method in that interface, then you'd just needif (myObject is INonGenericInterface x) { x.MethodFromInterface(); }
. – Jon Skeet Commented Mar 20 at 11:17