2015-09-22 5 views
0

У меня есть общие вспомогательные методы. Я хотел бы иметь возможность вызвать один из абстрактного класса, но у меня нет производного типа для перехода в метод Generic. Как мне это получить? Я также не хочу, чтобы абстрактный класс был общим. Это возможно?! вот код, который не работает ...: '(Общий класс помощников, вызванный из абстрактного класса

public abstract class Base 
{ 
    public bool Save() 
    { 
     try 
     { 
      Helper<this.GetType()>.Save(this); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
} 

И вспомогательный класс код

public class Helper<T> where T: class 
{ 
    public static bool Save(T obj) 
    { 
     try 
     { 
      Context.DDBContext.Save<T>(obj); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
} 

Если вы хотите больше кода, пожалуйста, спросите

+3

Недостаточно ли передать «Помощник» . Сохраните (это); '? Кажется, это объект, который можно сохранить. –

+0

Я не думал об этом gimmie секунду, чтобы посмотреть, работает ли это :) – Adween

+0

@TimSchmelter вы знаете, я думаю, что у вас есть это, это ковариация и контравариантность в действии, не так ли ...: D всплывает, и я буду отмечать он как правильный – Adween

ответ

2

Просто предложение, вы можете также определить помощник как метод расширения, перенести общий тип параметра для метода, ограничить параметр типа к Base, и вы можете вызвать его из производного типа, как будто оно происходит в базе:

public static class Helper 
{ 
    public static bool Save<T>(this T obj) where T: Base 
    { 
     try 
     { 
      Context.DBContext.Save<T>(obj); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    }    
} 

public class Derived : Base{} 

var x = new Derived(); 
x.Save(); 

Затем вы можете удалить Base.Save полностью.

+0

Интересно! позвольте мне попробовать – Adween

+0

ok это намного лучше и чище спасибо! :) – Adween

1

Ваш абстрактный базовый класс. не может «знать» тип любого производного класса.

Передайте вызов вашему вспомогательному методу производному классу, например, путем определения абстрактного виртуального метода в базовом классе:

protected abstract void Save(…); 

Затем, вместо прямого вызова метода-помощника, вызовите этот абстрактный метод. Производные классы могут переопределить его, они будут знать свой тип:

sealed class Derived : Base 
{ 
    protected override void Save(…) 
    { 
     Helper<Derived>.Save(this); 
    } 
} 
+0

да, но тогда в каждом производном типе я бы повторял тот же код. Я пытаюсь избежать этого – Adween

+0

@Adween - нет другого способа. это то, о чем ОО, а также абстрактные классы. абстрактный класс не может знать классы, которые происходят от него, но несколько «принуждает» производные классы переопределять абстрактные члены. вы говорите, что в каждом производном классе вы будете повторять код - какой код? –

+0

@Addeen: ваше использование дженериков более или менее * обеспечивает * это. Если вы не можете передать «Base» в качестве аргумента для параметра типового типа «T» и «Derived» в качестве аргумента для параметра 'obj'' Save', тогда все это не понадобится, и вы 'd всегда вызывать 'Помощник . Сохраните (это)'. – stakx

Смежные вопросы