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;
}
}
Related
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).
We are using HttpSessionStateBase to store messages in a set up similar to this working example:
public class HttpSessionMessageDisplayFetch : IMessageDisplayFetch
{
protected HttpSessionStateBase _session;
private IList<ICoreMessage> messages
{
get
{
if (_session[EchoCoreConstants.MESSAGE_KEY] == null)
_session[EchoCoreConstants.MESSAGE_KEY] = new List<ICoreMessage>();
return _session[EchoCoreConstants.MESSAGE_KEY] as IList<ICoreMessage>;
}
}
public HttpSessionMessageDisplayFetch()
{
if (HttpContext.Current != null)
_session = new HttpSessionStateWrapper(HttpContext.Current.Session);
}
public void AddMessage(ICoreMessage message)
{
if (message != null)
messages.Add(message);
}
public IEnumerable<IResultPresentation> FlushMessagesAsPresentations(IResultFormatter formatter)
{
var mToReturn = messages.Select(m => m.GetPresentation(formatter)).ToList();
messages.Clear();
return mToReturn;
}
}
When we pass in a QualityExplicitlySetMessage (which inherits from ICoreMessage, see below) it is saved correctly to messages.
This is how the object looks after being inserted into the messages list, at the end of AddMessage(ICoreMessage message) above.
But when we come to access it after changing controllers the inherited member's properties are null, which causes a variety of null reference exceptions.
This is how the object now looks after we call FlushMessagesAsPresentations. I've commented out var mToReturn... as this tries to access one of these null ref properties.
I'd like to ask the following:
Why is the HttpSessionStateBase failing to capture these values taken
by the inherited type?
Is this an issue in saving to the HttpSession or in retrieving?
Is this anything to do with, as I suspect, inheritance?
Or is the fact I'm potentially calling a new controller that dependency injects the HttpSessionMessageDisplayFetch causing an issue?
I'm a first-time poster so please let me know if I'm making any kind of faux pas - Super keen to learn! Any input is very welcome.
Some potentially useful code snippets:
QualityExplicitlySetMessage
public class QualityExplicitlySetMessage : QualityChangeMessage
{
public QualityExplicitlySetMessage(IQPossession before, IQPossession after, IQEffect qEffect)
: base(before, after, qEffect)
{
IsSetToExactly = true;
}
}
QualityChangeMessage - Working example
public abstract class QualityChangeMessage : CoreMessage, IQualityChangeMessage
{
protected PossessionChange Change;
public PossessionChange GetPossessionChange()
{
return Change;
}
protected QualityChangeMessage(IQPossession before, IQPossession after, IQEffect qEffect)
{
Change = new PossessionChange(before, after, qEffect);
StoreQualityInfo(qEffect.AssociatedQuality);
}
public override IResultPresentation GetPresentation(IResultFormatter formatter)
{
return formatter.GetQualityResult(this);
}
#region IQualityChangeMessage implementation
public int LevelBefore
{
get { return Change.Before.Level; }
}
//... And so on with values dependent on the Change property.
}
CoreMessage - Working example
public abstract class CoreMessage : ICoreMessage
{
public string MessageType
{
get { return GetType().ToString(); }
}
public string ImageTooltip
{
get { return _imagetooltip; }
set { _imagetooltip = value; }
}
public string Image
{
get { return _image; }
set { _image = value; }
}
public int? RelevantQualityId { get; set; }
protected void StoreQualityInfo(Quality q)
{
PyramidNumberIncreaseLimit = q.PyramidNumberIncreaseLimit;
RelevantQualityId = q.Id;
RelevantQualityName = q.Name;
ImageTooltip = "<strong>" + q.Name + "</strong><br/>" + q.Description + "<br>" +
q.EnhancementsDescription;
Image = q.Image;
}
public virtual IResultPresentation GetPresentation(IResultFormatter formatter)
{
return formatter.GetResult(this);
}
}
UserController - Working example.
public partial class UserController : Controller
{
private readonly IMessageDisplayFetch _messageDisplayFetch;
public UserController(IMessageDisplayFetch messageDisplayFetch)
{
_messageDisplayFetch = messageDisplayFetch;
}
public virtual ActionResult MessagesForStoryletWindow()
{
var activeChar = _us.CurrentCharacter();
IEnumerable<IResultPresentation> messages;
messages = _messageDisplayFetch.FlushMessagesAsPresentations(_storyFormatter);
var vd = new MessagesViewData(messages)
{
Character = new CharacterViewData(activeChar),
};
return View(Views.Messages, vd);
}
}
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.
I have a base class Rules.cs. There are 2 derived classes RowRules.cs and ColumnRules.cs. I have another class Test.cs. This class has a Dictionary <int, Rules> which keeps adding the values. When I loop through the dictionary I need to know if the value is a RowRule or a ColumnRule. To better understand I have the code below.
Rules.cs
class Rules
{
private int m_timepointId = 0;
private int m_studyId = 0;
public int TimepointId
{
get { return m_timepointId; }
set { m_timepointId = value;}
}
public int StudyId
{
get { return m_studyId; }
set {m_studyId = value; }
}
}
RowRules.cs
class RowRules : Rules
{
private int m_row;
public int Row
{
get { return m_row; }
set { m_row = value; }
}
}
ColumnRules.cs
class ColumnRules: Rules
{
private int m_column;
public int Column
{
get { return m_column; }
set { m_column = value; }
}
}
In the main class I have
private Dictionary<int, Rules> m_testDictionary = new Dictionary<int, Rules>();
ColumnRules columnrules = new ColumnRules();
RowRules rowRules = new RowRules();
rowRules.Row = 1;
rowRules.StudyId = 1;
m_testDictionary.Add(1, rowRules);
columnRules.Column = 2;
columnRules.TimepointId = 2;
m_testDictionary.Add(2, columnRules);
foreach(.... in m_testDictionary)
{
//Need code here.
//if(... == RowRules)
{
}
}
Now, I need to know what value will go in the foreach loop. Also, I need to know whether that particular dictionary row is a RowRule or a ColumnRule. Hope I am clear with the question. Any help will be really appreciated.
There are a bunch of answers that are telling you to test the type using "is". That's fine, but in my opinion if you're switching off the type of an object, you're probably doing something wrong.
Typically, derived classes are used when you need additional and varied functionality from a base class. Moreover, ad-hoc polymorphism via virtual and abstract methods means that you can let the run-time figure out the type, leading to significantly cleaner code.
For example, in your case, you might want to make Rules an abstract class, with an abstract ApplyRule() method. Then, each subclass can implement the method, with the full knowledge of what it means to be a rule of that type:
public class Rules
{
private int m_timepointId = 0;
private int m_studyId = 0;
public int TimepointId
{
get { return m_timepointId; }
set { m_timepointId = value;}
}
public int StudyId
{
get { return m_studyId; }
set {m_studyId = value; }
}
// New method
public abstract void ApplyRule();
}
class RowRules : Rules
{
private int m_row;
public int Row
{
get { return m_row; }
set { m_row = value; }
}
public override void ApplyRule() { // Row specific implementation }
}
class ColumnRules : Rules
{
private int m_column;
public int Column
{
get { return m_column; }
set { m_column = value; }
}
public override void ApplyRule() { // Column specific implementation }
}
Now, your loop is just:
foreach(var kvp in m_testDictionary)
{
kvp.Value.ApplyRule();
}
This should work:
foreach(KeyValuePair<int, Rules> pair in m_testDictionary)
{
if(pair.Value is RowRule)
{
// do row rule stuff
}
if(pair.Value is ColumnRule)
{
// do row column rule stuff
}
}
Here is more information on the is keyword.
Try the following
foreach(var rule in in m_testDictionary.Values)
{
var rowRules = rule as RowRules;
if (rowRules != null) {
// It's a RowRules
continue;
}
var columnRules = rule as ColumnRules;
if (columnRules != null) {
// It's a ColumnRules
continue;
}
}
You can try this:
foreach(var key in m_testDictionary.Keys)
{
var value = m_testDictionary[key];
if(value is RowRules)
{
//test your code.....
}
}
does that code work? You have added the same key twice I believe. This is the code you wanted I believe:
foreach(int key in m_testDictionary.Keys)
{
RowRules row = m_testDictionary[key] as RowRules;
if(row !=null)
{
//code here:)
}
}
I'm creating a table from a dynamically created IBindingList using
class TableBuilder
{
private Type m_TableType;
// ... create and define m_TableType here
public IBindingList CreateTable()
{
return Activator.CreateInstance(m_TableType) as IBindingList;
}
}
class DynamicTable : IBindingList
{
private IBindingList m_theList;
private TableBuilder m_tableBuilder;
public DynamicTable(TableBuilder tableBuilder)
{
m_tableBuilder = tableBuilder;
m_theList = tableBuilder.CreateTable();
}
public void LoadData()
{
// ...
}
}
I would like to promote the IBindingList functionality of m_theList to the level of the class so I can make calls like
var myTable = new DynamicTable(someTableBuilder);
int count = myTable.Count;
myTable.LoadData();
count = myTable.Count;
How can I get all the m_theList public members to be members of DynamicTable. I can not derive DynamicTable from m_TableType since it is only known at run time.
-Max
You will have to do it as old subclassing, implement the interface and in each method call the corresponding method in m_theList:
//methods
public void AddIndex(PropertyDescriptor property)
{
m_theList.AddIndex(property);
}
public object AddNew()
{
return m_theList.AddNew();
}
//properties
public bool AllowEdit
{
get { return m_theList.AllowEdit; }
}
....
//for events you can use add/remove syntax
public event ListChangedEventHandler ListChanged
{
add { m_theList.ListChanged += value; }
remove { m_theList.ListChanged -= value; }
}
....
//indexer...
public object this[int index]
{
get
{
return m_theList[index];
}
set
{
m_theList[index] = value;
}
}