Можно получить и добавленные и удаленные строки с журналом мерзавца, как:
git log --shortstat --reverse --pretty=oneline
От этого, можно записать подобный сценарий в тот, который Вы сделали использование этой информации В Python:
#!/usr/bin/python
"""
Display the per-commit size of the current git branch.
"""
import subprocess
import re
import sys
def main(argv):
git = subprocess.Popen(["git", "log", "--shortstat", "--reverse",
"--pretty=oneline"], stdout=subprocess.PIPE)
out, err = git.communicate()
total_files, total_insertions, total_deletions = 0, 0, 0
for line in out.split('\n'):
if not line: continue
if line[0] != ' ':
# This is a description line
hash, desc = line.split(" ", 1)
else:
# This is a stat line
data = re.findall(
' (\d+) files changed, (\d+) insertions\(\+\), (\d+) deletions\(-\)',
line)
files, insertions, deletions = ( int(x) for x in data[0] )
total_files += files
total_insertions += insertions
total_deletions += deletions
print "%s: %d files, %d lines" % (hash, total_files,
total_insertions - total_deletions)
if __name__ == '__main__':
sys.exit(main(sys.argv))
Почему вы создание экземпляра Orangutan
, если предполагается, что вы принимаете какой-либо IAnimal
?
public void ValidateUsing<T>(Action<T> action) where T : IAnimal, new()
{
T animal = new T();
action(animal); //Compile error 2
Если вы повторно используете свой общий параметр, у вас не будет проблем с типом ...
Теперь Что касается того, почему ваш код не работает, все, что вы говорите, - это то, что тип T
будет производным от IAnimal
. Однако это может быть так же легко Жираф
, как Орангутанг
, так что вы можете '
Попробуйте следующее.
Orangutan orangutan = new Orangutan();
Action<IAnimal> castedAction = action as Action<IAnimal>;
castedAction(orangutan);
Дело в том, что T представляет некоторый тип, который, кстати, реализует IAnimal.
Итак,
Внесите следующие изменения:
Orangutan orangutan = new Orangutan();
action((T)(IAnimal)orangutan);
IAnimal animal = new Orangutan();
action((T)animal);
public interface IAnimal { }
public class Orangutan : IAnimal { }
public void ValidateUsing<T>(Action<T> action) where T : IAnimal
{
Orangutan orangutan = new Orangutan();
action((T)(orangutan as IAnimal)); // needs to be cast as IAnimal
//This doesn't work either:
IAnimal animal = new Orangutan();
action((T)animal); // needs to be cast as T
}
Также кажется, что тот факт, что это интерфейс, имеет значение. Если бы у вас был абстрактный класс Animal, вместо интерфейса, вы могли бы сделать это:
public abstract class Animal { }
public class Orangutan : Animal { }
public void ValidateUsing<T>(Action<T> action) where T : Animal
{
Orangutan orangutan = new Orangutan();
action(orangutan as T);
//This doesn't work either:
Animal animal = new Orangutan();
action(animal as T);
}