Здравствуйте, Lloyd, Вы писали:
G>>А твой пример не расширяется до поиска любого обращения.
L>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то.
Ну допиши
L>Кстати, ты попустил вопрос: L>
L>Да и как этот ответ связан с использованием визитора?
Здравствуйте, gandjustas, Вы писали:
G>>>А твой пример не расширяется до поиска любого обращения.
L>>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то. G> Ну допиши
Ну допишу. Ты в это время свой вариант не забудь подготовить.
L>>Кстати, ты попустил вопрос: L>>
L>>Да и как этот ответ связан с использованием визитора?
G>Как допишешь — так узнаешь
Да уж сообщи мне, если знаешь. Вдруг ты действительно прав.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>А твой пример не расширяется до поиска любого обращения.
L>>>Почему не расширяется? Допиши нужную логику в HasStaticFieldWrite и всех делов-то. G>> Ну допиши
L>Ну допишу. Ты в это время свой вариант не забудь подготовить.
public class FindStaticReferencesVisitor: BaseCodeTraverser
{
public static bool HasStaticReferences(IMethodDefinition method)
{
var visitor = new FindStaticReferencesVisitor();
visitor.Visit(method);
return visitor.staticReferences.Any();
}
List<ITypeDefinitionMember> staticReferences = new List<ITypeDefinitionMember>();
public override void Visit(ITargetExpression targetExpression)
{
CollectStaticReferences(targetExpression.Definition);
base.Visit(targetExpression);
}
public override void Visit(IBoundExpression boundExpression)
{
CollectStaticReferences(boundExpression.Definition);
base.Visit(boundExpression);
}
private void CollectStaticReferences(object definition)
{
if (definition is IFieldDefinition)
{
var fieldDef = definition as IFieldDefinition;
if (fieldDef.IsStatic)
{
staticReferences.Add(fieldDef);
}
}
if (definition is IPropertyDefinition)
{
var propertyDef = definition as IPropertyDefinition;
if (propertyDef.Accessors.Select(a => a.ResolvedMethod).All(m => m.IsStatic))
{
staticReferences.Add(propertyDef);
}
}
}
}
class Program
{
static string assemblyName;
static void Main(string[] args)
{
assemblyName = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
var host = new CodeContractAwareHostEnvironment();
IAssembly assembly = host.LoadUnitFrom(assemblyName) as IAssembly;
if (assembly == null || assembly == Dummy.Assembly)
{
Console.WriteLine("Error");
}
else
{
var codeAssembly = Decompiler.GetCodeModelFromMetadataModel(host, assembly, null);
var q = from t in codeAssembly.AllTypes
from m in t.Methods
where FindStaticReferencesVisitor.HasStaticReferences(m)
select m;
var method = q.First();
Console.WriteLine(method.Name);
}
}
}
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>Вот как-то так.
L>Да, действительно, самому читать — чрезчур много писанины получается.
Это "чрезчур много писанины" называется визитором.
Здравствуйте, gandjustas, Вы писали:
L>>Да, действительно, самому читать — чрезчур много писанины получается.
G>Это "чрезчур много писанины" называется визитором.
G>Вот и ответ на твой вопрос.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
L>>>Да, действительно, самому читать — чрезчур много писанины получается.
G>>Это "чрезчур много писанины" называется визитором.
G>>Вот и ответ на твой вопрос.
L>Нет, визитор тут не причем.
Здравствуйте, gandjustas, Вы писали:
G>>>Это "чрезчур много писанины" называется визитором.
G>>>Вот и ответ на твой вопрос.
L>>Нет, визитор тут не причем.
G> G>Может все таки напишешь а там посмотрим?
Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>Это "чрезчур много писанины" называется визитором.
G>>>>Вот и ответ на твой вопрос.
L>>>Нет, визитор тут не причем.
G>> G>>Может все таки напишешь а там посмотрим?
L>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".
Здравствуйте, gandjustas, Вы писали:
L>>>>Нет, визитор тут не причем.
G>>> G>>>Может все таки напишешь а там посмотрим?
L>>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".
G>Ок, напиши свое решение и посмотрим.
Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
L>>>>>Нет, визитор тут не причем.
G>>>> G>>>>Может все таки напишешь а там посмотрим?
L>>>Я уже написал, что в моем варианте писанины будет много. У тебя получилось компактнее. Но это не далает мое решение "визитором".
G>>Ок, напиши свое решение и посмотрим.
L>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.
Ну тогда ты не можешь сказать какого вида получится конструкция.
А я такие конструкции писал, и уверен что у тебя будет визитор.
Здравствуйте, gandjustas, Вы писали:
G>>>Ок, напиши свое решение и посмотрим.
L>>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.
G>Ну тогда ты не можешь сказать какого вида получится конструкция. G>А я такие конструкции писал, и уверен что у тебя будет визитор.
Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.
Здравствуйте, Lloyd, Вы писали:
L>Здравствуйте, gandjustas, Вы писали:
G>>>>Ок, напиши свое решение и посмотрим.
L>>>Ты читаешь сообщения, на которые отвечаешь? Я же написал, что писанины много и писать его я не хочу.
G>>Ну тогда ты не можешь сказать какого вида получится конструкция. G>>А я такие конструкции писал, и уверен что у тебя будет визитор.
L>Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.
А если в этом "банальном FlattenTree" изолировать сам обход от алгоритма обработки, чтобы обход дерева можно было переиспользовать, то получится визитор.
Здравствуйте, gandjustas, Вы писали:
L>>Будет банальный FlattenTree, уплощающий дерево в плоский список. Это типа SelectMany, но который идет не на один уровень, а вглубь.
G>А если в этом "банальном FlattenTree" изолировать сам обход от алгоритма обработки, чтобы обход дерева можно было переиспользовать, то получится визитор.
Не получится: алгоритм обхода и так изолирован в FlattenTree.
Единственное преимущество visitor-а — это то, что он сам будет выбирать нужный метод обработки, но в этом случае, имхо, удобнее вынести алгоритм диспетчеризации в отдельный класс. Так что никаких преимуществ у визитора в данном случае не просматривается.