Проблема, над которой я нахожусь, связана с mappers в ASP.NET MVC, но это слишком сложно для публикации на SO, поэтому я упростил проблему, которая у меня ниже , Сначала я отправлю свой код, так как легче объяснить, что я пытаюсь достичь после кода.C# Наследование с помощью Generics и динамическое ключевое слово
Поддержка Code
public abstract class BaseFoo
{
public int CommonProperty { get; set; }
}
public class Foo1 : BaseFoo
{
public int SomeProperty { get; set; }
}
public class Foo2 : BaseFoo
{
public int AnotherProperty { get; set; }
}
public interface IMyInterface<T>
{
void SomeMethod(T t);
}
public abstract class BaseClass<T> : IMyInterface<T>
where T : BaseFoo
{
public virtual void SomeMethod(T t)
{
t.CommonProperty = 1;
}
}
public class ConcreteClass1 : BaseClass<Foo1>
{
public override void SomeMethod(Foo1 t)
{
t.SomeProperty = 57;
base.SomeMethod(t);
}
}
public class ConcreteClass2 : BaseClass<Foo2>
{
public override void SomeMethod(Foo2 t)
{
t.AnotherProperty = 123;
base.SomeMethod(t);
}
}
public static class ConcreteClassFactory
{
public enum ConcreteClassType
{
ConcreteClass1,
ConcreteClass2
}
public static dynamic CreateClass(ConcreteClassType type)
{
dynamic toReturn = null;
switch (type)
{
case ConcreteClassType.ConcreteClass1:
toReturn = new ConcreteClass1();
break;
case ConcreteClassType.ConcreteClass2:
toReturn = new ConcreteClass2();
break;
default:
break;
}
return toReturn;
}
}
То, что я хочу сделать, это динамически создавать различные ConcreteClass
с и называют SomeMethod
на этом созданный объект, в основном я хочу передать вокруг моего ConcreteClass
с, как BaseClass
, так же, как вы можете перейдите около Foo
с BaseFoo
. Я получил его на работу со следующим кодом:
class Program
{
static void Main(string[] args)
{
BaseFoo foo = new Foo1();
dynamic bar = ConcreteClassFactory.CreateClass(ConcreteClassFactory.ConcreteClassType.ConcreteClass1);
bar.SomeMethod(foo as dynamic);
}
}
Однако, это, кажется, очень запутано, чтобы бросить в динамике (также не в полной мере понять, почему удаление as dynamic
бросает RuntimeBinderException
, если кто-то может объяснить, что это будет оценено по достоинству). Есть ли лучший способ достичь того, что я пытаюсь сделать здесь?
Что вы хотите, чтобы произошло, когда кто-то проходит Foo2, чтобы ConcreteClass1? –
Я понимаю, что мой оригинальный код не показал, почему я хотел иметь 'ConcreteClass1', чтобы использовать' Foo1' в качестве его параметра. @ScottChamberlain, если 'ConcreteClass1' должен был получить' Foo2', он должен выбросить ошибку. Очевидно, я мог бы избавиться от дженериков и иметь «SomeMethod (BaseFoo t)», но затем в каждом производном классе мне нужно попробовать и применить к 't' к типу, который он ожидает, а не ужасно, но не идеален для моих целей –