I have code
public sealed class GameBoardComponent : IComponent {
}
// next code auto generated
public partial class Entity {
public GameBoardComponent gameBoard { get { return (GameBoardComponent)GetComponent(GameComponentIds.GameBoard); } }
public bool hasGameBoard { get { return HasComponent(GameComponentIds.GameBoard); } }
public Entity AddGameBoard(int newColumns, int newRows) {
var component = CreateComponent<GameBoardComponent>(GameComponentIds.GameBoard);
component.columns = newColumns;
component.rows = newRows;
return AddComponent(GameComponentIds.GameBoard, component);
}
public Entity ReplaceGameBoard(int newColumns, int newRows) {
var component = CreateComponent<GameBoardComponent>(GameComponentIds.GameBoard);
component.columns = newColumns;
component.rows = newRows;
ReplaceComponent(GameComponentIds.GameBoard, component);
return this;
}
public Entity RemoveGameBoard() {
return RemoveComponent(GameComponentIds.GameBoard);
}
}
I want to highlight or click on GameBoardComponent.
And to find all references to gameBoard, hasGameBoard, AddGameBoard, ReplaceGameBoard, RemoveGameBoard.
For AnotherComponent:
public sealed class AnotherComponent : IComponent { }
I would have to find another, hasAnother, AddAnother, ReplaceAnother, RemoveAnother
Is it possible to make a macro\regexp\resharper pattern search or something similar?
P.S. I try use resharper pattern search. But I did not understand how to use for search, selected string(or part of string).
Related
I have created a custom selector attribute, that filters what customers will appear in the popup box based on the user's ID.
But I have run into the problem that I can't seem to customize it like a normal selector
ie:
[PXSelector(typeof(Search2<InventoryItem.inventoryID, LeftJoin<INItemQtyCost, On<InventoryItem.inventoryID, Equal<INItemQtyCost.inventoryID>>>>),
typeof(InventoryItem.inventoryCD), typeof(InventoryItem.descr), typeof(INItemQtyCost.qtyAvail)
SubstituteKey = typeof(InventoryItem.inventoryCD),
Filterable = true)]
And can only use my custom selector attribute like this:
[SalesRepCustomer]
The constructor for the PXCustomSelectorAttribute is as follows:
public SalesRepCustomer() : base(typeof(Customer.bAccountID))
{
this.DescriptionField = typeof(Customer.acctName);
this.SubstituteKey = typeof(Customer.acctCD);
}
Is there a way to use the search2<> and so on in a PXCustomSelectorAttribute?
The whole point of a PXCustomSelectorAttribute is to override the "GetItems" method where you define the search function used to return records:
From https://asiablog.acumatica.com/2016/09/custom-selector-attribute.html
public class CustomerPriceClassAttribute : PXCustomSelectorAttribute
{
public CustomerPriceClassAttribute()
: base(typeof(ARPriceClass.priceClassID))
{
this.DescriptionField = typeof(ARPriceClass.description);
}
protected virtual IEnumerable GetRecords()
{
foreach (ARPriceClass pc in PXSelect<ARPriceClass>.Select(this._Graph))
{
yield return pc;
}
}
}
You can use PXSelectJoin or other PXSelect classes if you want.
Utilization of the PXSelectorAttribute
public class SalesRepCustomer : PXSelectorAttribute
{
public SalesRepCustomer() : base(typeof(Search<Customer.bAccountID>))
{
}
}
Usage would be as follows :
public class BatchExtension : PXCacheExtension<Batch>
{
public abstract class usrSalesRepCustomerID : BqlInt.Field<usrSalesRepCustomerID>
{
}
[SalesRepCustomer(SubstituteKey = typeof(Customer.acctName), DescriptionField = typeof(Customer.legalName))]
public int? UsrSalesRepCustomerID
{
get; set;
}
}
I have 2 classes Folder and File. They have a property NumberFiles. For File, it's of course only 1 at all case, for Folder, it depends how many files in the folder. This property must implement RaisePropertyChanged to bind.
I don't allow a set NumberFiles in FileRecord. But I can't find a solution, so this is my hack. With this code, I can set NumberFiles, but it doesn't have any effect.
public abstract class Record : ViewModelBase
{
private int _numberFiles;
public virtual int NumberFiles
{
get
{
return _numberFiles;
}
set
{
_numberFiles= value;
RaisePropertyChanged(nameof(NumberFiles));
}
}
//and a lot of properties
}
public class FolderRecord : Record
{
//and a lot of properties
}
public class FileRecord : Record
{
public override int NumberFiles
{
get
{
return 1;
}
set
{
//HACK : let empty SET
}
}
//and a lot of properties
}
public Main()
{
var list = new List<Record>(); // this list used to bind to the DataGrid
Record rc;
for (some condition)
{
if (folder)
{
rc = new RecordFolder();
rc.NumberFiles = 10; // OK
}
else if (file)
{
rc = new FileRecord();
rc.NumberFiles = 10; // the property NumberFiles can't allow a set, should compile error here
}
list.Add(rc);
}
}
I already have tried like put protected set in the base class but I can't set the value later.
public abstract class Record
{
public abstract int GetNumberFiles();
}
public class FolderRecord : Record
{
private int _numberOfFiles;
public void SetNumberOfFiles(int numberOfFiles)
{
_numberOfFiles = numberOfFiles;
}
public override int GetNumberFiles()
{
return _numberOfFiles;
}
}
public class FileRecord : Record
{
public override int GetNumberFiles()
{
return 1;
}
}
My brain is gonna to explode. :) So I would like to get help from you.
Please, think about my question like about just programmer puzzle. (Actually. perhaps it is very easy question for you, but not for me.)
It is needed to create array of objects. For example List where T is class. (I will describe Class T below). Also it is needed create “container” that will contain this array and some methods for work with this array. For example Add(), Remove(int IndexToRemove).
Class T must have field "Container", this way each elements of our array would be able to know where is it contained and has access its container's fields and methods. Notice, that in this case Class T should have type parameter. Indeed, it is not known beforehand which container's type is used.
Let us denote this class container as A and class element (class T) as AUnit.
Code:
class Program
{
static void Main(string[] args)
{
A a = new A();
a.Add();
a.Units[0].SomeField +=100;
Console.ReadKey();
}
}
class A
{
public List<AUnit> Units;
public A()//ctor
{
Units = new List<AUnit>();
}
public void Add()
{
this.Units.Add(new AUnit(this));
}
}
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
}
Public fields should be protected or private of course, but let think about this later.
You can ask “why we create public A Container field in AUnit”? We create field public string Name{get;private set;} (actually property but nevermind). And also we would like to be able to change value of this field for example method [Class AUnit] public bool Rename(string newName)();. The main idea of this method is changing Name field only that case if no one element in array (public List Units; ) has the same name like newName. But to achieve this, Rename method has to have access to all names that is currently used. And that is why we need Container field.
Code of extended version AUnit
class AUnit
{
public int SomeField;
public A Container;
public string Name { get; private set; }
public AUnit(A container)
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (AUnit unt in this.Container.Units)
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
Ok. If you still read it let's continue. Now we need to create Class B and class BUnit which will be very similar like Class A and Class Aunit. And finally the main question of this puzzle is HOW WE CAN DO IT? Of course, I can CopyPaste and bit modify A and AUnit and create this code.
class B
{
public List<BUnit> Units; //Only Type Changing
public B()//ctor Name changing...
{
Units = new List<BUnit>();//Only Type Changing
}
public void Add()
{
this.Units.Add(new BUnit(this));//Only Type Changing
}
}
class BUnit
{
public int SomeField;
public B Container;//Only Type Changing
public string Name { get; private set; }
public A a; //NEW FIELD IS ADDED (just one)
public BUnit(B container) //Ctor Name and arguments type changing
{
this.SomeField = 43;
this.Container = container;
this.Name = "Default";
this.a=new A(); //New ROW (just one)
}
public bool Rename(String newName)
{
Boolean res = true;
foreach (BUnit unt in this.Container.Units) //Only Type Changing
{
if (unt.Name == newName)
{
res = false;
break;
}
}
if (res) this.Name = String.Copy(newName);
return res;
}
}
And I can to use this classes this way.
static void Main(string[] args)
{
B b = new B();
b.Add();
b.Units[0].a.Add();
b.Units[0].a.Units[0].SomeField += 100;
bool res= b.Units[0].a.Units[0].Rename("1");
res = b.Units[0].a.Units[0].Rename("1");
Console.ReadKey();
}
This construction is can be used to create “non-homogeneous trees”.
Help, I need somebody help, just no anybody…. [The Beatles]
I created B and BUnit using CopyPaste.
But how it can be done using “macro-definitions” or “Generic”, inherit or anything else in elegant style? (C# language)
I think that there is no reason to describe all my unsuccessful attempts and subquestions. Already topic is too long. : )
Thanks a lot if you still read it and understand what I would like to ask.
You need to implement a base type, lets call it UnitBase, with all common functionality. I'd structure your code the following way:
Create an interface for your container, this way you can change implementation to more performant solutions without modifying the elements you will be adding to the container.
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
}
Following the idea stated in 1, why not make the search logic belong to the container? It makes much more sense, as it will mostly depend on how the container is implemented:
public interface IContainer
{
Q Add<Q>() where Q : UnitBase, new();
IEnumerable<UnitBase> Units { get; }
bool Contains(string name);
}
A specific implementation of IContainer could be the following:
public class Container : IContainer
{
public Container()
{
list = new List<UnitBase>();
}
private List<UnitBase> list;
public Q Add<Q>() where Q: UnitBase, new()
{
var newItem = Activator.CreateInstance<Q>();
newItem.SetContainer(this);
list.Add(newItem);
return newItem;
}
public IEnumerable<UnitBase> Units => list.Select(i => i);
public bool Contains(string name) =>
Units.Any(unit => unit.Name == name);
}
Create a base class for your AUnit and BUnit types condensing all common functionality:
public abstract class UnitBase
{
protected UnitBase()
{
}
public IContainer Container { get; private set; }
public int SomeField;
public string Name { get; private set; }
public void SetContainer(IContainer container)
{
Container = container;
}
public bool Rename(String newName)
{
if (Container.Contains(newName))
return false;
this.Name = newName; //No need to use String.Copy
return true;
}
}
Implement your concrete types:
public class BUnit : UnitBase
{
public int SpecificBProperty { get; private set; }
public BUnit()
{
}
}
Shortcomings of this approach? Well, the container must be of type <UnitBase>, I've removed the generic type because it really wasn't doing much in this particular case as it would be invariant in the generic type.
Also, keep in mind that nothing in the type system avoids the following:
myContainer.Add<BUnit>();
myContainer.Add<AUnit>();
If having two different types in the same container is not an option then this whole set up kind of crumbles down. This issue was present in the previous solution too so its not something new, I simply forgot to point it out.
InBetween , I am very thankful to you for your advices. Actually I can't say that I understood your answer in full, but using your ideas I have done what I want.
Looks like my variant works well. However I would like to hear your (and everyone) opinions about code described below. The main goal of this structure is creating non-homogeneous trees. So could you estimate it from this side.
First of all. We need to create interfaces for both classes. We describe there all "cross-used" functions.
public interface IUnit<T>
{
string Name { get;}
void SetContainer(T t);
bool Rename(String newName);
}
public interface IContainer
{
bool IsNameBusy(String newName);
int Count { get; }
}
Next. Create Base for Unit Classes for future inheritance. We will use in this inheritors methods from Container Base so we need generic properties and IUnit interface.
class UnitBase<T> : IUnit<T> where T : IContainer
Unfortunately I don't know yet how to solve the problem with Constructor parameters. That is why I use method
SetContainer(T container).
Code:UnitBase
class UnitBase<T> : IUnit<T> where T : IContainer
{
protected T Container;
public string Name { get; private set; }
public UnitBase()
{
this.Name = "Default";
}
public void SetContainer(T container)
{
this.Container = container;
}
public bool Rename(String newName)
{
bool res = Container.IsNameBusy(newName);
if (!res) this.Name = String.Copy(newName);
return !res;
}
}
Next. Create ContainerBase
ContainerBase should:
1) has IContainer interface.
2)has information about what it will contain:
... where U : IUnit<C>, new()
3)and .... has information about what itself is. This information we need to pass as parameter to SetContainer() method.
Code ContainerBase:
class ContainerBase<U, C> : IContainer //U - Unit Class. C-Container Class
where U : IUnit<C>, new()
where C : ContainerBase<U, C>
{
protected List<U> Units;
public U this[int index] { get { return Units[index]; } }
public ContainerBase()//ctor
{
this.Units = new List<U>();
}
public void Add()
{
this.Units.Add(new U());
this.Units.Last().SetContainer(((C)this));//may be a bit strange but actualy this will have the same type as <C>
}
public bool IsNameBusy(String newName)
{
bool res = false;
foreach (var unt in this.Units)
{
if (unt.Name == newName)
{
res = true;
break;
}
}
return res;
}
public int Count { get { return this.Units.Count; } }
}
Cast ((TContainer)(this)) may be is a bit strange. But using ContainerBase we always should use NewInheritorContainer. So this cast is just do nothing…looks like...
Finally. This classes can be used like in this example.
class SheetContainer : ContainerBase<SheetUnit,SheetContainer> {public SheetContainer(){}}
class SheetUnit : UnitBase<SheetContainer>
{
public CellContainer Cells;
public PictureContainer Pictures;
public SheetUnit()
{
this.Cells = new CellContainer();
this.Pictures = new PictureContainer();
}
}
class CellContainer : ContainerBase<CellUnit, CellContainer> { public CellContainer() { } }
class CellUnit : UnitBase<CellContainer>
{
public string ValuePr;//Private Field
private const string ValuePrDefault = "Default";
public string Value//Property for Value
{
//All below are Just For Example.
get
{
return this.ValuePr;
}
set
{
if (String.IsNullOrEmpty(value))
{
this.ValuePr = ValuePrDefault;
}
else
{
this.ValuePr = String.Copy(value);
}
}
}
public CellUnit()
{
this.ValuePr = ValuePrDefault;
}
}
class PictureContainer : ContainerBase<PictureUnit, PictureContainer> { public PictureContainer() { } }
class PictureUnit : UnitBase<PictureContainer>
{
public int[,] Pixels{get;private set;}
public PictureUnit()
{
this.Pixels=new int[,]{{10,20,30},{11,12,13}};
}
public int GetSizeX()
{
return this.Pixels.GetLength(1);
}
public int GetSizeY()
{
return this.Pixels.GetLength(0);
}
public bool LoadFromFile(string path)
{
return false;
}
}
static void Main(string[] args)
{
SheetContainer Sheets = new SheetContainer();
Sheets.Add();
Sheets.Add();
Sheets.Add();
Sheets[0].Pictures.Add();
Sheets[1].Cells.Add();
Sheets[2].Pictures.Add();
Sheets[2].Cells.Add();
Sheets[2].Cells[0].Value = "FirstTest";
bool res= Sheets[0].Rename("First");//res=true
res=Sheets[2].Rename("First");//res =false
int res2 = Sheets.Count;
res2 = Sheets[2].Pictures[0].Pixels[1, 2];//13
res2 = Sheets[2].Pictures.Count;//1
res2 = Sheets[1].Pictures.Count;//0
res2 = Sheets[0].Pictures[0].GetSizeX();//3
Console.ReadKey();
}
Looks like it works like I want. But I didn’t test it full.
Let me say Thank you again, InBetween.
Can we make a property of a class visible to public , but can only be modified by some specific classes?
for example,
// this is the property holder
public class Child
{
public bool IsBeaten { get; set;}
}
// this is the modifier which can set the property of Child instance
public class Father
{
public void BeatChild(Child c)
{
c.IsBeaten = true; // should be no exception
}
}
// this is the observer which can get the property but cannot set.
public class Cat
{
// I want this method always return false.
public bool TryBeatChild(Child c)
{
try
{
c.IsBeaten = true;
return true;
}
catch (Exception)
{
return false;
}
}
// shoud be ok
public void WatchChild(Child c)
{
if( c.IsBeaten )
{
this.Laugh();
}
}
private void Laugh(){}
}
Child is a data class,
Parent is a class that can modify data,
Cat is a class that can only read data.
Is there any way to implement such access control using Property in C#?
Rather than exposing the inner state of the Child class you could provide a method instead:
class Child {
public bool IsBeaten { get; private set; }
public void Beat(Father beater) {
IsBeaten = true;
}
}
class Father {
public void BeatChild(Child child) {
child.Beat(this);
}
}
Then the cat can't beat your child:
class Cat {
public void BeatChild(Child child) {
child.Beat(this); // Does not compile!
}
}
If other people need to be able to beat the child, define an interface they can implement:
interface IChildBeater { }
Then have them implement it:
class Child {
public bool IsBeaten { get; private set; }
public void Beat(IChildBeater beater) {
IsBeaten = true;
}
}
class Mother : IChildBeater { ... }
class Father : IChildBeater { ... }
class BullyFromDownTheStreet : IChildBeater { ... }
This is usually achieved by using separate assemblies and the InternalsVisibleToAttribute. When you mark the set with internal classes within the current assembly will have access to it. By using that attribute, you can give specific other assemblies access to it. Remember by using Reflection it will still always be editable.
The design problem is as follows, actual problem consists of 2 modules.
Module 1 classes (External Assembly)
abstract class Letter
{
private int _id;
protected Letter(int id) { _id = id; }
public abstract string Val { get; }
}
class LetterA : Letter
{
public LetterA(int id) : base(id) {}
public override string Val
{
get { return "A"; }
}
}
class WordWithALettersOnly
{
public IList<LetterA> ALetters { get; set; }
}
Module 2 classes
class LetterSmallA : LetterA
{
public LetterSmallA(int id) : base(id) {}
public override string Val
{
get { return "a"; }
}
}
class WordWithSmallALettersOnly : WordWithALettersOnly
{
private IList<LetterSmallA> _aLetters;
public new IList<LetterSmallA> ALetters
{
get { return _aLetters; }
set
{
_aLetters = value;
if(_aLetters != null)
base.ALetters = value.Cast<LetterA>().ToList(); // <-- reference lost
}
}
}
class Program
{
static void Main(string[] args)
{
var smallAWordOnly = new WordwithSmallALettersOnly();
smallAWordOnly.ALetters = new List<LetterSmallA>(){new LetterSmallA(1)};
Console.WriteLine("d : " + smallAWordOnly.ALetters.Count); // --> 1
Console.WriteLine("b : " + ((WordwithALettersOnly)smallAWordOnly).ALetters.Count); // --> 1
smallAWordOnly.ALetters.Add(new LetterSmallA(2)); --> 2
Console.WriteLine("d : " + smallAWordOnly.ALetters.Count);
Console.WriteLine("b : " + ((WordwithALettersOnly)smallAWordOnly).ALetters.Count); // -> 1
}
}
Essentially derived classes are generated in the module 2 and processed in the external assembly module 1, on a/c reference loss.
Is the only way to translate the derived class objects of the module 2 to module 1 class objects
I hope i have been explain clearly the issue, if not i do apologise, would really appreciate solutions to this.
If I understand your question correctly, what you want is to treat IList<LetterSmallA> as IList<LetterA>. This is not possible in C# and for very good reasons: one of the things IList<LetterA> says is possible to do with is is to “try to add any LetterA to it. This is not possible with IList<LetterSmallA> and so there is no built-in way to do what you want.
What you can do is to create your own implementation of IList<T> that wraps another IList<T> of derived type:
class BaseTypeList<TBase, TDerived> : IList<TBase>
where TBase : class
where TDerived : class, TBase
{
private readonly IList<TDerived> m_derivedList;
public BaseTypeList(IList<TDerived> derivedList)
{
m_derivedList = derivedList;
}
public IEnumerator<TBase> GetEnumerator()
{
return m_derivedList.Cast<TBase>().GetEnumerator();
}
public void Add(TBase item)
{
var derivedItem = item as TDerived;
if (derivedItem == null)
throw new ArgumentException();
m_derivedList.Add(derivedItem);
}
public void Clear()
{
m_derivedList.Clear();
}
// other members implemented in a similar fashion
}
(The class constraints are not necessary, but make some code simpler.)
Your setter for ALetters could then look like this:
_aLetters = value;
if(_aLetters == null)
base.ALetters = null;
else
base.ALetters = new BaseTypeList<LetterA, LetterSmallA>(value);